llamar - ¿Los navegadores analizan javascript en cada carga de página?
llamar funcion javascript html sin evento (6)
Creo que la respuesta correcta sería "no siempre". Por lo que entiendo, tanto el navegador como el servidor juegan un papel en la determinación de lo que se almacena en caché. Si realmente necesita que los archivos se vuelvan a cargar cada vez, entonces creo que debería poder configurar eso desde Apache (por ejemplo). Por supuesto, supongo que el navegador del usuario podría configurarse para ignorar esa configuración, pero eso probablemente sea poco probable.
Así que me imagino que, en la mayoría de los casos prácticos, los archivos javascript se guardan en caché, pero se vuelven a interpretar dinámicamente cada vez que se carga la página.
¿Los navegadores (IE y Firefox) analizan los archivos javascript vinculados cada vez que la página se actualiza?
Pueden almacenar en caché los archivos, así que supongo que no intentarán descargarlos cada vez, pero como cada página está esencialmente separada, espero que eliminen cualquier código anterior y lo vuelvan a analizar.
Esto es ineficiente, aunque perfectamente comprensible, pero me pregunto si los navegadores modernos son lo suficientemente inteligentes como para evitar el paso de análisis dentro de los sitios. Estoy pensando en casos en que un sitio utiliza una biblioteca de JavaScript, como ExtJS o jQuery, etc.
El navegador definitivamente hace uso del almacenamiento en caché, pero sí, los navegadores analizan el JavaScript cada vez que una página se actualiza. Porque cada vez que el navegador carga una página, crea 2 árboles 1. Árbol de contenido y árbol de 2.render.
Este árbol de renderizado consiste en la información sobre el diseño visual de los elementos dom. Por lo tanto, cada vez que se carga una página, el javascript se analiza y cualquier cambio dinámico realizado por el javascript le agrada posicionar el elemento dom, mostrar / ocultar elemento, agregar / quitar elemento hará que el navegador vuelva a crear el árbol de renderizado. Pero los broswers modernos como FF y Chrome lo manejan de forma ligeramente diferente, tienen el concepto de renderizado incremental, por lo que cada vez que haya cambios dinámicos por el js como se mencionó anteriormente, solo hará que esos elementos se rendericen y vuelvan a pintar.
Estos son los detalles que he podido desenterrar. Vale la pena señalar en primer lugar que aunque JavaScript se considera interpretado y ejecutado en una máquina virtual, este no es realmente el caso con los intérpretes modernos, que tienden a compilar la fuente directamente en el código máquina (a excepción de IE).
Chrome: motor V8
V8 tiene un caché de compilación. Esto almacena JavaScript compilado usando un hash de la fuente para hasta 5 colecciones de basura. Esto significa que dos partes idénticas de código fuente compartirán una entrada de caché en la memoria, independientemente de cómo se incluyeron. Este caché no se borra cuando las páginas se vuelven a cargar.
Actualización - 19/03/2015
El equipo de Chrome ha publicado detalles sobre sus nuevas técnicas para la transmisión y el almacenamiento en caché de JavaScript .
- Streaming de scripts
La transmisión de secuencias de comandos optimiza el análisis de archivos JavaScript. [...]
A partir de la versión 41, Chrome analiza las secuencias de comandos asíncronas y diferidas en una secuencia separada tan pronto como la descarga haya comenzado. Esto significa que el análisis puede completarse solo milisegundos después de que la descarga haya finalizado, y los resultados en las páginas se cargan hasta un 10% más rápido.
- Caché de código
Normalmente, el motor V8 compila el JavaScript de la página en cada visita, convirtiéndolo en instrucciones que un procesador entiende. Este código compilado se descarta una vez que el usuario navega fuera de la página, ya que el código compilado depende en gran medida del estado y el contexto de la máquina en el momento de la compilación.
Chrome 42 introduce una técnica avanzada para almacenar una copia local del código compilado, de modo que cuando el usuario regrese a la página, todos los pasos de descarga, análisis y compilación se puedan omitir. En todas las cargas de página, esto permite que Chrome evite aproximadamente el 40% del tiempo de compilación y ahorre una batería preciosa en dispositivos móviles.
Opera: Motor de Carakan
En la práctica, esto significa que cada vez que un programa de script está a punto de compilarse, cuyo código fuente es idéntico al de algún otro programa que se compiló recientemente, reutilizamos el resultado anterior del compilador y omitimos por completo el paso de compilación. Este caché es bastante efectivo en escenarios de navegación típicos donde uno carga página tras página desde el mismo sitio, como diferentes artículos de noticias de un servicio de noticias, ya que cada página a menudo carga la misma biblioteca de scripts, a veces muy grande.
Por lo tanto, JavaScript se almacena en caché a través de recargas de página, dos solicitudes al mismo script no darán lugar a una recompilación.
Firefox: Motor SpiderMonkey
SpiderMonkey utiliza Nanojit
como su back-end nativo, un compilador JIT. El proceso de compilación del código de máquina se puede ver here . En resumen, parece recompilar los scripts a medida que se cargan. Sin embargo, si echamos un vistazo más de cerca a las Nanojit
internas de Nanojit
vemos que el monitor de nivel superior jstracer
, que se usa para rastrear la compilación, puede pasar por tres etapas durante la compilación, proporcionando un beneficio para Nanojit
:
El estado inicial del monitor de seguimiento es la supervisión. Esto significa que spidermonkey está interpretando bytecode. Cada vez que spidermonkey interpreta un byte de salto hacia atrás, el monitor anota la cantidad de veces que saltó el valor del contador de programa de salto (PC). Este número se llama conteo de visitas para la PC. Si el conteo de aciertos de una PC en particular alcanza un valor umbral, el objetivo se considera caliente.
Cuando el monitor decide que una PC objetivo está caliente, se ve en una tabla hash de fragmentos para ver si hay un fragmento que contenga código nativo para esa PC objetivo. Si encuentra un fragmento así, pasa al modo de ejecución. De lo contrario, pasa al modo de grabación.
Esto significa que para hot
fragmentos hot
de código, el código nativo se almacena en caché. Lo que significa que no será necesario volver a compilar. No queda claro si estas secciones nativas hash se conservan entre actualizaciones de página. Pero supongo que lo son. Si alguien puede encontrar evidencia de apoyo para esto, entonces excelente.
EDITAR : Se ha señalado que el desarrollador de Mozilla Boris Zbarsky ha declarado que Gecko aún no almacena en caché los guiones compilados. Tomado de esta respuesta SO .
Safari: JavaScriptCore / SquirelFish Engine
Creo que la mejor respuesta para esta implementación ya ha sido dada por otra persona .
Actualmente no almacenamos en caché el bytecode (o el código nativo). Es un
opción que hemos considerado, sin embargo, actualmente, la generación de código es una
porción trivial del tiempo de ejecución de JS (<2%), por lo que no estamos persiguiendo
esto en este momento.
Esto fue escrito por Maciej Stachowiak , el desarrollador principal de Safari. Entonces creo que podemos tomar eso para ser verdad.
No pude encontrar ninguna otra información, pero puedes leer más sobre las mejoras de velocidad del último motor SquirrelFish Extreme
here , o navegar por el código fuente here si te sientes aventurero.
IE: Chakra Engine
No hay información actual sobre el Motor de JavaScript de IE9 (Chakra) en este campo. Si alguien sabe algo, por favor comente.
Esto no es oficial, pero para las implementaciones de motores anteriores de IE, Eric Lippert ( un desarrollador de MS de JScript ) afirma en un blog que here :
JScript Classic actúa como un lenguaje compilado en el sentido de que antes de que se ejecute cualquier programa JScript Classic, verificamos completamente el código, generamos un árbol de análisis completo y generamos un bytecode. Luego ejecutamos el bytecode a través de un intérprete de código de bytes. En ese sentido, JScript está tan "compilado" como Java. La diferencia es que JScript no le permite persistir o examinar nuestro bytecode patentado . Además, el bytecode es mucho más alto que el bytecode de JVM: el lenguaje de bytecode de JScript Classic es poco más que una linealización del árbol de análisis sintáctico, mientras que el bytecode de JVM está claramente destinado a operar en una máquina de stack de bajo nivel.
Esto sugiere que el bytecode no persiste de ninguna manera y, por lo tanto, bytecode no se almacena en caché.
No vale la pena que Google Dart aborde explícitamente este problema a través de "Instantáneas": el objetivo es acelerar la inicialización y el tiempo de carga cargando la versión preparsed del código.
InfoQ tiene una buena redacción @ http://www.infoq.com/articles/google-dart
Opera lo hace, como se menciona en la otra respuesta. ( Source )
Firefox (motor SpiderMonkey) no almacena en caché el bytecode. ( fuente )
WebKit (Safari, Konqueror) no almacena en caché el bytecode. ( fuente )
No estoy seguro acerca de IE [6/7/8] o V8 (Chrome), creo que IE podría hacer algún tipo de almacenamiento en caché, mientras que V8 podría no hacerlo. IE es de código cerrado, así que no estoy seguro, pero en V8 puede no tener sentido almacenar en caché el código "compilado", ya que compilan directamente en el código máquina.
Por lo que yo sé, solo Opera almacena en caché el JavaScript analizado. Consulte la sección "Programas compilados en caché" Source .