web-dev-qa-db-fra.com

Les navigateurs analysent-ils le javascript à chaque chargement de page?

Les navigateurs (IE et Firefox) analysent-ils les fichiers javascript liés à chaque actualisation de la page?

Ils peuvent mettre en cache les fichiers, donc je suppose qu'ils n'essaieront pas de les télécharger à chaque fois, mais comme chaque page est essentiellement séparée, je m'attends à ce qu'ils détruisent tout ancien code et le ré-analysent.

C'est inefficace, bien que parfaitement compréhensible, mais je me demande si les navigateurs modernes sont assez intelligents pour éviter l'étape d'analyse dans les sites. Je pense aux cas où un site utilise une bibliothèque javascript, comme ExtJS ou jQuery, etc.

185
Steve Jones

Ce sont les détails que j'ai pu creuser. Il convient de noter d'abord que bien que JavaScript soit généralement considéré comme interprété et exécuté sur une machine virtuelle, ce n'est pas vraiment le cas avec les interprètes modernes, qui ont tendance à compiler la source directement dans le code machine (à l'exception d'IE).


Chrome: moteur V8

V8 possède un cache de compilation. Cela stocke le code JavaScript compilé à l'aide d'un hachage de la source pour jusqu'à 5 récupérations de place. Cela signifie que deux morceaux de code source identiques partageront une entrée de cache en mémoire, quelle que soit la façon dont ils ont été inclus. Ce cache n'est pas effacé lorsque les pages sont rechargées.

Source


Mise à jour - 19/03/2015

L'équipe Chrome a publié détails sur leurs nouvelles techniques de streaming et de mise en cache JavaScript .

  1. 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 séparé dès que le téléchargement a commencé. Cela signifie que l'analyse peut se terminer en quelques millisecondes une fois le téléchargement terminé, et les résultats en pages chargement jusqu'à 10% plus rapide.

  1. Mise en cache du code

Normalement, le moteur V8 compile le JavaScript de la page à chaque visite, le transformant en instructions compréhensibles par un processeur. Ce code compilé est ensuite supprimé une fois qu'un utilisateur s'éloigne de 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 sur la page, les étapes de téléchargement, d'analyse et de compilation peuvent toutes être ignorées. Dans tous les chargements de pages, cela permet à Chrome d'éviter environ 40% du temps de compilation et d'économiser une batterie précieuse sur les appareils mobiles.


Opera: 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 récemment compilé, nous réutilisons la sortie précédente du compilateur et sautons entièrement 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, tels que différents articles de nouvelles d'un service de nouvelles, car chaque page charge souvent la même bibliothèque de scripts, parfois très grande.

Par conséquent, JavaScript est mis en cache lors des rechargements de page, deux requêtes vers le même script n'entraîneront pas de recompilation.

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 apparaît pour recompiler les scripts lors de leur chargement. Cependant, si nous y regardons de plus près à l'intérieur de Nanojit nous voyons que le moniteur de niveau supérieur jstracer, qui est utilisé pour suivre la compilation peut passer par trois étapes pendant la compilation, offrant un avantage à 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 prend note du nombre de fois que la valeur du compteur de programme cible (PC) a été sautée. Ce nombre est appelé le nombre de hits pour le PC. Si le nombre de hits 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 y a 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 hot fragments de code, le code natif est mis en cache. Ce qui 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 page. Mais je suppose qu'ils le sont. Si quelqu'un peut trouver des preuves à l'appui, alors excellent.

[~ # ~] modifier [~ # ~] : Il a été souligné que le développeur de Mozilla Boris Zbarsky a déclaré que Gecko ne mettait pas en cache les scripts compilés yet. Tiré de this SO answer .


Safari: JavaScriptCore/SquirelFish Engine

Je pense que la meilleure réponse pour cette implémentation a déjà donnée par quelqu'un d'autre .

Nous ne mettons actuellement pas en cache le bytecode (ou le code natif). C'est un
option que nous avons envisagée, cependant, actuellement, la génération de code est un
partie triviale du temps d'exécution de JS (<2%), donc nous ne poursuivons pas
ceci 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 de la dernière SquirrelFish Extreme engine ici , ou parcourez le code source ici si vous vous sentez aventureux.


IE: moteur de chakra

Il n'y a aucune information actuelle concernant le moteur JavaScript d'IE9 (Chakra) dans ce domaine. Si quelqu'un sait quelque chose, veuillez commenter.

Ceci est assez officieux, mais pour les implémentations de moteur plus anciennes d'IE, Eric Lippert ( n 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 de tout 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 persister ou d'examiner notre bytecode propriétaire . En outre, le bytecode est beaucoup plus élevé que le bytecode JVM - le langage de bytecode JScript Classic n'est guère plus qu'une linéarisation de l'arbre d'analyse, tandis 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 aucune façon, et donc le bytecode n'est pas mis en cache.

333
Jivings

Opera le fait, comme mentionné dans l'autre réponse. ( source )

Firefox (moteur SpiderMonkey) ne pas cache le bytecode. ( source )

WebKit (Safari, Konqueror) ne pas cache le bytecode. ( source )

Je ne suis pas sûr de IE [6/7/8] ou V8 (Chrome), je pense que IE pourrait faire une sorte de mise en cache alors que V8 peut ne pas. IE est une source fermée, donc je ne suis pas sûr, mais dans la version 8, cela peut ne pas avoir de sens de mettre en cache le code "compilé" car ils compilent directement en code machine.

12
cha0site

Pour autant que je sache, seul Opera met en cache le JavaScript analysé. Voir la section "Programmes compilés en cache" ici .

3
gsnedders

Cela ne vaut rien que Google Dart s'attaque explicitement à ce problème via des "instantanés" - le but est d'accélérer l'initialisation et le temps de chargement en chargeant la version pré-préparée du code.

InfoQ a une bonne rédaction @ http://www.infoq.com/articles/google-Dart

2
igrigorik

Le navigateur utilise certainement la mise en cache mais oui, les navigateurs analysent le JavaScript à chaque actualisation d'une page. Parce que chaque fois qu'une page est chargée par le navigateur, elle crée 2 arborescences: 1. arborescence de contenu et 2. arborescence de rendu.

Cet arbre de rendu se compose des informations sur la disposition visuelle des éléments dom. Ainsi, chaque fois qu'une page se charge, le javascript est analysé et toute modification dynamique par le javascript aimera positionner l'élément dom, afficher/masquer l'élément, ajouter/supprimer un élément, le navigateur recréera l'arborescence de rendu. Mais les navigateurs modernes comme FF et chrome le gèrent légèrement différemment, ils ont le concept de rendu incrémentiel, donc chaque fois qu'il y a des changements dynamiques par le js comme mentionné ci-dessus, cela ne fera que ces éléments rendre et repeindre à nouveau.

0
Abhidev

Je pense que la bonne réponse serait "pas toujours". D'après ce que je comprends, le navigateur et le serveur jouent un rôle dans la détermination de ce qui est mis en cache. Si vous avez vraiment besoin de fichiers à recharger à chaque fois, je pense que vous devriez être en mesure de configurer cela depuis Apache (par exemple). Bien sûr, je suppose que le navigateur de l'utilisateur pourrait être configuré pour ignorer ce paramètre, mais c'est probablement peu probable.

J'imagine donc que dans la plupart des cas pratiques, les fichiers javascript eux-mêmes sont mis en cache, mais sont réinterprétés dynamiquement à chaque chargement de la page.

0
Zachary Murray