¿Cuál es la mejor manera de cargar Javascript en una página para optimizar el rendimiento?

Respuestas:

14

Hay algunas cosas que puedes hacer:

  1. Cargue el HTML y CSS antes del javascript. Esto le da al navegador todo lo que necesita para diseñar la página y renderizarla. Esto le da al usuario la impresión de que la página es ágil. Coloque etiquetas o bloques de script tan cerca de la etiqueta del cuerpo de cierre como sea posible.

  2. Considere usar un CDN. Si está utilizando alguna de las bibliotecas populares como JQuery, muchas compañías (por ejemplo, google, yahoo) operan CDN gratuitas que puede usar para cargar las bibliotecas.

  3. Cargue código desde un archivo externo en lugar de un script incrustado. Esto le da al navegador la oportunidad de almacenar en caché el contenido de JS y no tener que cargarlo en absoluto. Las cargas de página sucesivas serán más rápidas.

  4. Active la compresión zip en el servidor web.

Yahoo tiene una gran página de sugerencias que pueden ayudar a reducir los tiempos de carga de la página.

Gareth Farrington
fuente
1
Yahoo también distribuye el complemento YSlow para Firefox, que analiza su página con respecto a las mejores prácticas mencionadas anteriormente y le entrega una boleta de calificaciones. Ver developer.yahoo.com/yslow
Alan
1
También hay técnicas como la carga asincrónica que se pueden usar si tiene elementos del sitio que no requieren que se cargue el script cuando la página se presenta inicialmente. Tanto esto como colocar el script cerca del final de la página tienen limitaciones; en algunos casos necesita cargar el JS en el encabezado del documento.
JasonBirch
7

Además de Minifing, gziping y CDNing (¿nueva palabra?). Debe considerar aplazar la carga. Básicamente, lo que hace es agregar los scripts dinámicamente y evitar el bloqueo, permitiendo descargas paralelas.

Hay muchas formas de hacerlo, esta es la que prefiero

<script type="text/javascript">
    function AttachScript(src) {
        window._sf_endpt=(new Date()).getTime();
        var script = document.createElement("script");
        document.getElementsByTagName("body")[0].appendChild(script);
        script.src = src;
    }
    AttachScript("/js/scripts.js");
    AttachScript("http://www.google-analytics.com/ga.js");
</script>

Coloque esto justo antes de la etiqueta del cuerpo de cierre y use AttachScript para cargar cada archivo js.
Más información aquí http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/

El desintegrador
fuente
1
Oye, robaste CDNing; se supone que significa hacer algo canadiense! ;)
JasonBirch
jajajaja good one
The Desintegrator
7

Es posible que desee ver también la forma en que Google carga Analytics:

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-xxxxxxx-x']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

Como se considera un tipo de script de "mejores prácticas":
http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/

Jeff Atwood
fuente
3

Un par de personas de Google anunciaron un nuevo proyecto de código abierto en Velocity 2010 llamado Diffable . Diffable realiza algo de magia para publicar de forma incremental solo las partes de JS, HTML y CSS que han cambiado desde la versión que está almacenada en la memoria caché del usuario, en lugar de enviar un nuevo archivo completo cuando se lanza una nueva versión.

Esta técnica es increíblemente genial, y actualmente es más efectiva (y vale la pena el esfuerzo) en sitios web donde está utilizando una gran base de código JavaScript con pequeños cambios frecuentes de código. Esto se aplica especialmente bien a aplicaciones como Google Maps, que se somete al menos a una versión todos los martes , y promedia alrededor de 100 nuevas versiones al año. También tiene mucho sentido en general una vez que el almacenamiento local HTML5 se generaliza.

Por cierto, si no ha visto a Michael Jones de Google hablar sobre el cambio (en un contexto geoespacial), vale la pena ver su discurso principal completo en GeoWeb 2009 .

JasonBirch
fuente
1

Para dar una actualización a esta pregunta. Creo que en la moderna, la forma de carga sin bloqueo ya no es necesaria, el navegador lo hará por usted.

He agregado una pregunta a StackOverflow, agregaré el contenido aquí también.

La única diferencia es que el evento de carga se disparará un poco antes, pero la carga de los archivos en sí sigue siendo la misma. También quiero agregar que incluso si la carga se dispara antes con el script sin bloqueo, esto no significa que los archivos JS se hayan disparado antes. En mi caso, la configuración normal salió mejor

Ahora primero los guiones, se ven así:

<script>
(function () {
    var styles = JSON.parse(myObject.styles);
    for( name in styles ){
        var link  = document.createElement('link');
        link.setAttribute('rel', 'stylesheet');
        link.setAttribute('type', 'text/css');
        link.setAttribute('href', styles[name]);
        document.getElementsByTagName('head')[0].appendChild(link);
    }

    var scripts = JSON.parse(myObject.scripts);
    for( name in scripts ){
        var e = document.createElement('script');
        e.src = scripts[name];
        e.async = true;
        document.getElementsByTagName('head')[0].appendChild(e);
    }
}());
</script>

myObject.styles Aquí hay un objeto que contiene todas las URL de todos los archivos.

He ejecutado 3 pruebas, aquí están los resultados:

Configuración normal

Carga de página con CSS en la cabeza y JavaScript en la parte inferior

Esta es solo la configuración normal, tenemos 4 archivos css en la cabeza y 3 archivos css en la parte inferior de la página.

Ahora no veo nada bloqueando. Lo que veo es que todo se está cargando al mismo tiempo.

JS sin bloqueo

Carga de página con JavaScript sin bloqueo

Ahora, para llevar esto un poco más lejos, SOLO hice que los archivos js no sean bloqueantes. Esto con el guión de arriba. De repente veo que mis archivos CSS están bloqueando la carga. Esto es extraño, porque no está bloqueando nada en el primer ejemplo. ¿Por qué css bloquea repentinamente la carga?

Todo sin bloqueo

Carga de página con todo lo que no sea de bloqueo

Finalmente hice una prueba en la que todos los archivos externos se cargan de manera no bloqueante. Ahora no veo ninguna diferencia con nuestro primer método. Ambos se ven iguales.

Conclusión

Mi conclusión es que los archivos ya están cargados de manera no bloqueante, no veo la necesidad de agregar un script especial.

¿O me estoy perdiendo algo aquí?

Más:

Saif Bechan
fuente
La diferencia es la ubicación de la línea azul, que supongo que es cuando la página comienza a representarse. Desde el punto de vista del usuario final, esto es cuando la página está "cargada", ya que es cuando comienzan a ver cosas. En el primer ejemplo, el renderizado comienza después de cargar el último archivo JS, en la marca de 900 ms. En el segundo, es después de cargar las hojas de estilo (~ 700ms). En el tercero, es después de que se haya descargado el HTML (~ 500 ms). Seguiría con el segundo enfoque, ya que realmente no quieres cargar CSS después de que se renderice la página.
Fuente de Tim