Ce sont les détails que j'ai pu déterrer. Il convient de noter tout d'abord que bien que JavaScript soit généralement considéré comme interprété et exécuté sur une VM, ce n'est pas vraiment le cas avec les interpréteurs modernes, qui ont tendance à compiler la source directement dans le code machine (à l'exception d'IE).
Chrome: moteur V8
V8 a un cache de compilation. Cela stocke le JavaScript compilé à l'aide d'un hachage de la source pour jusqu'à 5 garbage collection. Cela signifie que deux morceaux identiques de code source partageront une entrée de cache en mémoire quelle que soit la manière dont ils ont été inclus. Ce cache n'est pas effacé lorsque les pages sont rechargées.
La source
Mise à jour - 19/03/2015
L'équipe Chrome a publié des détails sur ses nouvelles techniques de streaming et de mise en cache JavaScript .
- Streaming de script
Le streaming de scripts optimise l'analyse des fichiers JavaScript. [...]
À partir de la version 41, Chrome analyse les scripts asynchrones et différés sur un thread distinct dès que le téléchargement a commencé. Cela signifie que l'analyse peut se terminer quelques millisecondes seulement après la fin du téléchargement et que les pages se chargent jusqu'à 10% plus rapidement.
- Mise en cache du code
Normalement, le moteur V8 compile le JavaScript de la page à chaque visite, le transformant en instructions qu'un processeur comprend. Ce code compilé est ensuite rejeté une fois qu'un utilisateur quitte la page car le code compilé dépend fortement de l'état et du contexte de la machine au moment de la compilation.
Chrome 42 introduit une technique avancée de stockage d'une copie locale du code compilé, de sorte que lorsque l'utilisateur revient à la page, les étapes de téléchargement, d'analyse et de compilation peuvent toutes être ignorées. Sur tous les chargements de pages, cela permet à Chrome d'éviter environ 40% du temps de compilation et d'économiser une précieuse batterie sur les appareils mobiles.
Opéra: moteur Carakan
En pratique, cela signifie que chaque fois qu'un programme de script est sur le point d'être compilé, dont le code source est identique à celui d'un autre programme qui a été récemment compilé, nous réutilisons la sortie précédente du compilateur et sautons complètement l'étape de compilation. Ce cache est assez efficace dans les scénarios de navigation typiques où l'on charge page après page à partir du même site, comme différents articles de presse d'un service de news, car chaque page charge souvent la même bibliothèque de scripts, parfois très volumineuse.
Par conséquent, JavaScript est mis en cache lors des recharges de page, deux requêtes adressées au même script ne donneront pas lieu à une recompilation.
La source
Firefox: moteur SpiderMonkey
SpiderMonkey utilise Nanojit
comme back-end natif, un compilateur JIT. Le processus de compilation du code machine peut être vu ici . En bref, il semble recompiler les scripts au fur et à mesure de leur chargement. Cependant, si nous examinons de plus près les composants internes de, Nanojit
nous voyons que le moniteur de niveau supérieur jstracer
, qui est utilisé pour suivre la compilation, peut passer en trois étapes lors de la compilation, offrant un avantage pour Nanojit
:
L'état initial du moniteur de trace est la surveillance. Cela signifie que spidermonkey interprète le bytecode. Chaque fois que spidermonkey interprète un bytecode de saut en arrière, le moniteur note le nombre de fois où la valeur du compteur de programme (PC) de la cible de saut a été sautée. Ce nombre est appelé le nombre de succès pour le PC. Si le nombre de succès d'un PC particulier atteint une valeur seuil, la cible est considérée comme chaude.
Lorsque le moniteur décide qu'un PC cible est chaud, il regarde dans une table de hachage de fragments pour voir s'il existe un fragment contenant du code natif pour ce PC cible. S'il trouve un tel fragment, il passe en mode exécution. Sinon, il passe en mode d'enregistrement.
Cela signifie que pour les hot
fragments de code, le code natif est mis en cache. Cela signifie qu'il n'aura pas besoin d'être recompilé. Il n'est pas précisé si ces sections natives hachées sont conservées entre les actualisations de la page. Mais je suppose qu'ils le sont. Si quelqu'un peut trouver des preuves à l'appui, alors c'est excellent.
EDIT : Il a été souligné que le développeur de Mozilla Boris Zbarsky a déclaré que Gecko ne cache pas encore les scripts compilés . Tiré de cette réponse SO .
Safari: JavaScriptCore / SquirelFish Engine
Je pense que la meilleure réponse pour cette implémentation a déjà été donnée par quelqu'un d'autre .
Nous ne mettons actuellement pas en cache le bytecode (ou le code natif). C'est une
option que nous avons envisagée, cependant, actuellement, la génération de code est une
partie insignifiante du temps d'exécution de JS (<2%), nous ne poursuivons donc pas
cela pour le moment.
Ceci a été écrit par Maciej Stachowiak , le développeur principal de Safari. Je pense donc que nous pouvons considérer cela comme vrai.
Je n'ai pas pu trouver d'autres informations, mais vous pouvez en savoir plus sur les améliorations de vitesse du dernier SquirrelFish Extreme
moteur ici , ou parcourir le code source ici si vous vous sentez aventureux.
IE: moteur Chakra
Il n'y a pas d'informations actuelles concernant le moteur JavaScript d'IE9 (Chakra) dans ce champ. Si quelqu'un sait quelque chose, veuillez commenter.
C'est assez non officiel, mais pour les anciennes implémentations de moteur d'IE, Eric Lippert ( un développeur MS de JScript ) déclare dans une réponse de blog ici que:
JScript Classic agit comme un langage compilé en ce sens qu'avant l'exécution d'un programme JScript Classic, nous vérifions entièrement la syntaxe du code, générons un arbre d'analyse complet et générons un bytecode. Nous exécutons ensuite le bytecode via un interpréteur de bytecode. En ce sens, JScript est tout aussi "compilé" que Java. La différence est que JScript ne vous permet pas de conserver ou d'examiner notre bytecode propriétaire . De plus, le bytecode est beaucoup plus élevé que le bytecode JVM - le langage bytecode JScript Classic n'est guère plus qu'une linéarisation de l'arborescence d'analyse, alors que le bytecode JVM est clairement destiné à fonctionner sur une machine de pile de bas niveau.
Cela suggère que le bytecode ne persiste en aucun cas et que le bytecode n'est donc pas mis en cache.