L'intention initiale de cet article est de présenter comment utiliser quelques astuces de codage simples pour améliorer le JavaScript. compilateur Le processus d'optimisation améliore l'efficacité de l'exécution du code. Surtout dans les jeux où la vitesse de récupération de place est élevée, les utilisateurs verront un écran blanc si les performances sont légèrement médiocres.
JavaScript permet de transmettre des paramètres dynamiques lors de l'appel de fonctions, mais en prenant une simple fonction à 2 paramètres comme exemple, lorsque votre type de paramètre, le nombre de paramètres et le type de retour Il ne peut être déterminé que lorsqu'il est appelé dynamiquement, et le compilateur a besoin de plus de temps pour l'analyser. Les compilateurs veulent naturellement être capables de gérer des structures de données monomorphiquement prévisibles, des statistiques de paramètres, etc.
function example(a, b) { // we expect a, b to be numeric console.log(++a * ++b); }; example(); // bad example(1); // still bad example("1", 2); // dammit meg example(1, 2); // good
L'utilisation de constantes permet au compilateur d'effectuer le remplacement de la valeur de la variable lors de la compilation :
const a = 42; // we can easily unfold this const b = 1337 * 2; // we can resolve this expression const c = a + b; // still can be resolved const d = Math.random() * c; // we can only unfold 'c' // before unfolding a; b; c; d; // after unfolding // we can do this at compile time! 42; 2674; 2716; Math.random() * 2716;
Le Le compilateur JIT peut trouver les parties les plus exécutées de votre code. Le fractionnement de votre code en plusieurs petits blocs de code peut aider le compilateur à convertir ces blocs de code au format en ligne au moment de la compilation.
Utilisez autant que possible les nombres et les booléens car ils fonctionnent mieux que les autres types primitifs tels que les chaînes. L’utilisation de types de chaîne peut entraîner des coûts supplémentaires de récupération de place.
const ROBOT = 0; const HUMAN = 1; const SPIDER = 2; let E_TYPE = { Robot: ROBOT, Human: HUMAN, Spider: SPIDER }; // bad // avoid uncached strings in heavy tasks (or better in general) if (entity.type === "Robot") { } // good // the compiler can resolve member expressions // without much deepness pretty fast if (entity.type === E_TYPE.Robot) { } // perfect // right side of binary expression can even get unfold if (entity.type === ROBOT) { }
Utilisez l'opérateur de comparaison strict === au lieu de l'opérateur == autant que possible. L'utilisation d'opérateurs de comparaison stricts peut éviter au compilateur d'effectuer une déduction et une conversion de type, améliorant ainsi certaines performances.
L'instruction if en JavaScript est également très flexible. Vous pouvez directement transmettre n'importe quelle valeur similaire dans une instruction de sélection conditionnelle du type if(a) then bla. Cependant, dans ce cas, tout comme les opérateurs de comparaison stricts et les opérateurs de comparaison lâches mentionnés ci-dessus, le compilateur doit les convertir en plusieurs types de données à des fins de comparaison, et les résultats ne peuvent pas être obtenus immédiatement. Bien sûr, il ne s'agit pas de s'opposer aveuglément à l'utilisation d'abréviations, mais dans les scénarios qui mettent beaucoup l'accent sur les performances, il est recommandé d'optimiser chaque détail :
let a = 2; // bad // abstracts to check in the worst case: // - is value equal to true // - is value greater than zero // - is value not null // - is value not NaN // .. if (a) { // if a is true, do something } // good if (a === 2) { // do sth } // same goes for functions function b() { return (!false); }; if (b()) { // get in here slow } if (b() === true) { // get in here fast // the compiler knows a specific value to compare with }
Éviter comme autant que possible Utilisez la méthode arguments[index] pour obtenir les paramètres, et essayez d'éviter de modifier les variables de paramètre passées :
function mul(a, b) { return (arguments[0]*arguments[1]); // bad, very slow return (a*b); // good }; function test(a, b) { a = 5; // bad, dont modify argument identifiers let tmp = a; // good tmp *= 2; // we can now modify our fake 'a' };
sont répertoriés ci-dessous Plusieurs caractéristiques grammaticales affecteront le processus d'optimisation :
eval
avec
try/ catch
En même temps, essayez d'éviter de déclarer des fonctions ou des fermetures à l'intérieur des fonctions, ce qui pourrait entraîner trop d'opérations de garbage collection dans un grand nombre d'opérations.
Les instances d'objet partagent généralement des classes implicites, donc lorsque nous accédons ou définissons la valeur d'une variable non définie d'une instance, une classe implicite est créée.
// our hidden class 'hc_0' class Vector { constructor(x, y) { // compiler finds and expects member declarations here this.x = x; this.y = y; } }; // both vector objects share hidden class 'hc_0' let vec1 = new Vector(0, 0); let vec2 = new Vector(2, 2); // bad, vec2 got hidden class 'hc_1' now vec2.z = 0; // good, compiler knows this member vec2.x = 1;
Mettez en cache autant que possible la valeur calculée de la longueur du tableau et stockez autant que possible un seul type dans le même tableau. Évitez d'utiliser la syntaxe for-in pour parcourir un tableau car elle est très lente. De plus, les performances des instructions continue et break dans les boucles sont également bonnes, vous n'avez donc pas à vous en soucier lorsque vous les utilisez. De plus, divisez autant que possible les parties logiques courtes en fonctions indépendantes, ce qui est plus propice à l'optimisation du compilateur. De plus, l’utilisation d’expressions d’incrémentation automatique de préfixe peut également apporter de légères améliorations de performances. (je remplace i) La fonction
let badarray = [1, true, 0]; // bad, dont mix types let array = [1, 0, 1]; // happy compiler // bad choice for (let key in array) { }; // better // but always try to cache the array size let i = 0; for (; i < array.length; ++i) { key = array[i]; }; // good let i = 0; let key = null; let length = array.length; for (; i < length; ++i) { key = array[i]; };
draeImage est l'une des API Canvas 2D les plus rapides, mais nous devons faire attention si tous les paramètres sont omis pour des raisons de commodité. , augmentera également la perte de performances :
// bad ctx.drawImage( img, x, y ); // good ctx.drawImage( img, // clipping sx, sy, sw, sh, // actual stuff x, y, w, h ); // much hax // no subpixel rendering by passing integers ctx.drawImage( img, sx|0, sy|0, sw|0, sh|0, x|0, y|0, w|0, h|0 );
Ce qui précède est le contenu de l'écriture de JavaScript hautes performances. Pour plus de contenu connexe, veuillez prêter attention au site Web PHP chinois (www. php.cn) !