Maison > Article > interface Web > Comprendre et optimiser le code javascript
En tant qu'ingénieur front-end, tout le monde connaît JavaScript. Cet article examine une direction plus profonde : le moteur JS pour comprendre comment JavaScript s'exécute et l'optimiser.
Moteur JS——Introduction au moteur JS
1 Introduction de base
Le moteur js est un JavaScript spécialisé. interprète. Vous pouvez jeter un bref aperçu des moteurs js grand public actuels et de leurs introductions :
V8 — Le moteur V8 open source de Google utilisant C++ est également un moteur que nous entendons souvent
Rhino — Un moteur open source entièrement géré en Java par la Fondation Mozilla
SpiderMonkey — Le moteur js de première génération qui fonctionnait autrefois dans le navigateur Netscape Navigator . Maintenant Firefox
JavaScriptCore — Le moteur js open source de Safari
KJS — Moteur KDE, développé par Harri Porten
Chakra (JScript9) — Moteur Internet Explorer
Chakra (JavaScript) — Moteur Microsoft Edge
JerryScript — Moteur js léger , principalement utilisé pour l'IOT
2. Processus de fonctionnement du moteur V8
Maintenant, en raison de la popularité de NodeJS et de Google Chrome, nous présentons ici principalement le moteur V8 Le mécanisme de fonctionnement , si vous êtes intéressé par d'autres moteurs, vous pouvez le vérifier vous-même. Ils sont fondamentalement les mêmes
Nous pouvons voir que le processus de traitement du moteur JS consiste d'abord à analyser. et convertir L'arbre syntaxique AST est ensuite utilisé par l'interpréteur pour faire deux choses principales. La première est de le convertir en bytecode en langage machine, et la seconde est de le transmettre à l'éditeur (compilateur d'optimisation) pour l'optimisation. un processus d'analyse des données (profilage des données) au milieu, l'objectif principal est d'optimiser le fonctionnement de JS, puis de convertir le code optimisé en langage machine.
Les composants principaux causés par le V8 sont respectivement l'allumage et le TurboFan
Code JS—— Parler n'est pas cher
Quand vous verrez cela, vous penserez certainement, je sais à quoi ça sert, Talk n'est pas cher, y a-t-il un code qui peut être analysé ? Alors s'il vous plaît, jetez un œil à l'exemple de code suivant. Après avoir analysé le code, je présenterai le principe en détail
Exemple de code un :
// first case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 0; i < 9999999; i++) { b[i] = 0 } console.timeEnd() // second case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 10000000; i < 19999999; i++) { b[i] = 0 } console.timeEnd() // third case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 9999999; i < 0; i--) { b[i] = 0 } console.timeEnd()
Après avoir lu le code ci-dessus, le contenu est très simple, qui consiste à définir les objets a et b puis à continuer à ajouter des attributs. La seule différence est que dans le premier cas, a et b ajoutent à plusieurs reprises les mêmes attributs, dans le second cas, a et b ajoutent des attributs différents, et dans le deuxième cas, a et b ajoutent des attributs différents. troisième cas, a et b ajoutent à plusieurs reprises les mêmes attributs, mais le processus b est dans l'ordre inverse.
Alors la question est : y a-t-il une différence dans la vitesse d'exécution des trois morceaux de code, et la différence est-elle grande ? (Vous n'avez pas besoin de vérifier le nombre de cycles, c'est tout de même !)
Voici la réponse : le temps pris est d'environ 3 (500 ms)
Moteur V8 - Classe cachée
Nous savons que js est un langage de script dynamique. Qu'est-ce que cela signifie que vous pouvez facilement ajouter/supprimer des attributs au ? Ou changez son type. La plupart des interpréteurs js utilisent des structures de dictionnaire pour stocker les adresses des valeurs d'attributs variables en mémoire. Cette méthode est différente de Java et C# (langages non dynamiques, bien sûr, le type dynamique de C# en est un autre. important, sans entrer dans les détails ici) est beaucoup moins efficace, car le type de js peut être converti à tout moment, l'utilisation d'une structure de dictionnaire combinée à un type fixe pour le jugement peut faciliter la recherche de l'emplacement du. valeur d'attribut variable, mais elle est difficile à réaliser en js .
Le moteur V8 utilise donc une méthode très efficace appelée Hidden Class. D'autres moteurs ont également des méthodes similaires, notamment Map, Structures, Hidden Class, etc. Ici, nous utilisons Shape pour le définir, afin qu'il soit plus facile à comprendre pour tout le monde.
Lorsque nous définissons un objet, il contiendra le contenu suivant :
La signification de chaque attribut peut être Voir tableau ci-dessus.
Puis combiné avec Shape, lors de la définition d'un objet, le moteur JS créera une Shape (peut être comprise comme un tampon de cache continu), et ses positions 0 et 1 stockeront les valeurs x et y, comme indiqué ci-dessous :
Si je définis deux objets, contenant tous deux x et y, alors ils partageront une forme, comme indiqué ci-dessous :
Nous pouvons donc imaginer ici que tant que nous définissons des objets avec les mêmes attributs, ils partageront tous une forme. Lorsque nous voulons appeler la valeur d'attribut de n'importe quelle forme, nous pouvons utiliser le décalage de la même forme. Venez le chercher.
Alors, que se passe-t-il lorsque nous ajoutons des attributs à un objet ? Le moteur V8 créera une nouvelle forme pour marquer la position en fonction du principe de transition de classe, comme indiqué ci-dessous
En d'autres termes, nous avons créé 3 formes, à travers la chaîne de transition (chaîne de transition) pour réaliser la traçabilité d’un objet.
En voyant cela, tout le monde doit penser que chaque forme supplémentaire occupera certainement un morceau de mémoire supplémentaire donc pour l'optimisation, j'essaie de définir tous les attributs lors de l'initialisation pour optimiser, Bingo~ On peut se référer à la figure. ci-dessous pour vérifier :
Grâce à l'explication des principes ci-dessus, je pense que tout le monde sera capable de déduire et d'expliquer la différence dans la vitesse d'exécution de notre exemple de code.
Premier cas :
1. Forme (vide) pour a et b
2. Forme 1....9999999 pour a
3. Forme 1....9999999 pour b
a et b partagent la même forme et peuvent être réutilisés
Deuxième cas :
1. Forme (vide) pour a. et b
2. Forme 1....9999999 pour a
3. Forme 10000000....19999999 pour b
définit un total de 1 à 19999999 forme. , alors le deuxième cas prendra certainement deux fois plus de temps que le premier cas
Troisième cas :
1 Forme (vide) pour a et b
2. Forme 1. ....9999999 pour a
3. Forme 9999999....1 pour b
Code source : https://github.com/likeconan/Alipay_Wechat_Integration
Pour plus de connaissances sur JavaScript, veuillez faire attention à la colonne collection d'effets spéciaux js sur le site Web PHP chinois.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!