Esses são os detalhes que pude descobrir. Vale a pena notar primeiro que, embora o JavaScript geralmente seja considerado interpretado e executado em uma VM, esse não é realmente o caso dos intérpretes modernos, que tendem a compilar a fonte diretamente no código da máquina (com exceção do IE).
Chrome: motor V8
V8 possui um cache de compilação. Isso armazena o JavaScript compilado usando um hash da fonte para até 5 coletas de lixo. Isso significa que duas partes idênticas do código-fonte compartilharão uma entrada de cache na memória, independentemente de como foram incluídas. Esse cache não é limpo quando as páginas são recarregadas.
Fonte
Atualização - 19/03/2015
A equipe do Chrome divulgou detalhes sobre suas novas técnicas para streaming e cache de JavaScript .
- Script Streaming
O fluxo de scripts otimiza a análise de arquivos JavaScript. [...]
A partir da versão 41, o Chrome analisa scripts assíncronos e adiados em um thread separado assim que o download é iniciado. Isso significa que a análise pode concluir apenas milissegundos após o término do download e resulta no carregamento de páginas 10% mais rápidas.
- Cache de código
Normalmente, o mecanismo V8 compila o JavaScript da página a cada visita, transformando-o em instruções que um processador entende. Esse código compilado é descartado assim que um usuário navega para fora da página, pois o código compilado depende muito do estado e do contexto da máquina no momento da compilação.
O Chrome 42 apresenta uma técnica avançada de armazenamento de uma cópia local do código compilado, para que, quando o usuário retorne à página, as etapas de download, análise e compilação possam ser ignoradas. Em todos os carregamentos de página, isso permite que o Chrome evite cerca de 40% do tempo de compilação e economize bateria preciosa em dispositivos móveis.
Opera: Carakan Engine
Na prática, isso significa que sempre que um programa de script está prestes a ser compilado, cujo código-fonte é idêntico ao de algum outro programa recentemente compilado, reutilizamos a saída anterior do compilador e pulamos completamente a etapa de compilação. Esse cache é bastante eficaz em cenários de navegação típicos, onde se carrega página após página do mesmo site, como diferentes artigos de notícias de um serviço de notícias, pois cada página carrega frequentemente a mesma biblioteca de scripts, às vezes muito grande.
Portanto, o JavaScript é armazenado em cache nas recargas de página, duas solicitações para o mesmo script não resultarão em uma recompilação.
Fonte
Firefox: SpiderMonkey Engine
O SpiderMonkey usa Nanojit
como backend nativo, um compilador JIT. O processo de compilação do código da máquina pode ser visto aqui . Em resumo, parece recompilar scripts à medida que são carregados. No entanto, se examinarmos mais de perto os internos Nanojit
, veremos que o monitor de nível superior jstracer
, usado para rastrear a compilação, pode passar por três estágios durante a compilação, proporcionando um benefício para Nanojit
:
O estado inicial do monitor de rastreio é o monitoramento. Isso significa que o spidermonkey está interpretando o bytecode. Sempre que o spidermonkey interpreta um bytecode de salto para trás, o monitor anota o número de vezes que o valor do contador de programa (PC) do alvo de salto foi saltado. Esse número é chamado de contagem de ocorrências para o PC. Se a contagem de ocorrências de um PC em particular atingir um valor limite, o alvo será considerado quente.
Quando o monitor decide que um PC de destino está quente, ele procura em uma hashtable de fragmentos para ver se há um fragmento contendo o código nativo desse PC de destino. Se encontrar um fragmento, ele passa para o modo de execução. Caso contrário, ele passa para o modo de gravação.
Isso significa que para hot
fragmentos de código, o código nativo é armazenado em cache. Significado que não precisará ser recompilado. Não está claro se essas seções nativas de hash são mantidas entre as atualizações de página. Mas eu diria que eles são. Se alguém puder encontrar evidências de apoio a isso, então excelente.
EDIT : Tem sido apontado que o desenvolvedor Mozilla Boris Zbarsky afirmou que Gecko não cache de scripts compilados ainda . Retirado desta resposta SO .
Safari: JavaScriptCore / SquirelFish Engine
Penso que a melhor resposta para esta implementação já foi dada por outra pessoa .
No momento, não armazenamos em cache o bytecode (ou o código nativo). É uma
opção que consideramos, no entanto, atualmente, a geração de código é uma
parte trivial do tempo de execução do JS (<2%), portanto, não estamos buscando
isso no momento.
Isto foi escrito por Maciej Stachowiak , o principal desenvolvedor do Safari. Então, acho que podemos considerar isso verdade.
Não consegui encontrar nenhuma outra informação, mas você pode ler mais sobre as melhorias de velocidade do SquirrelFish Extreme
mecanismo mais recente aqui ou procurar o código fonte aqui se estiver se sentindo aventureiro.
IE: Motor de Chakra
Não há informações atuais sobre o JavaScript Engine do IE9 (Chakra) neste campo. Se alguém souber alguma coisa, comente.
Isto é completamente não-oficial, mas para implementações de motores mais velhos do IE, Eric Lippert ( um desenvolvedor de MS de JScript ) afirma em uma resposta do blog aqui que:
O JScript Classic age como uma linguagem compilada no sentido de que, antes de qualquer programa JScript Classic ser executado, verificamos totalmente o código, geramos uma árvore de análise completa e um bytecode. Em seguida, executamos o bytecode através de um interpretador de bytecode. Nesse sentido, o JScript é tão "compilado" quanto o Java. A diferença é que o JScript não permite que você persista ou examine nosso bytecode proprietário . Além disso, o bytecode é de nível muito superior ao bytecode da JVM - a linguagem de bytecode do JScript Classic é pouco mais que uma linearização da árvore de análise, enquanto o bytecode da JVM claramente se destina a operar em uma máquina de pilha de baixo nível.
Isso sugere que o bytecode não persiste de maneira alguma e, portanto, o bytecode não é armazenado em cache.