Optimizar la carga de archivos JavaScript y CSS (Carga no bloqueante o diferida)

Publicado el 25 septiembre 2014 por Programacionymas
¿Quieres aumentar la velocidad de tu página web? Solución: Optimiza la carga de archivos Javascript y CSS.

¿En qué consiste la optimización de la carga de archivos o carga diferida?

En pocas palabras, cuando accedemos a una página web, nuestro navegador analiza el código HTML a medida que lo descarga y si encuentra un archivo externo, detiene la descarga del HTML, inicia la descarga del archivo externo y una vez concluida esta segunda descarga continua con el resto del HTML.Este proceso provoca que las páginas necesiten más tiempo en cargar y la carga de una web a saltos.Para solucionar este problema, y aumentar así la velocidad de tu web, existe lo que se conoce como la carga diferida, carga optimizada de archivos o carga de archivos no bloqueante, método que permite al navegador descargar archivos externos una vez finalizada la descarga del código HTML de la web.

¿Cómo optimizar la carga de archivos Javascript o CSS?

Mediante el atributo "defer" (válido únicamente para JS)

Cuando declaramos un script en nuestro HTML, podemos establecer el atributo defer="defer" en nuestra etiqueta del script informando al navegador de que este archivo debe ser cargado una vez finalizada la carga del DOM de la web.Esto únicamente tiene una pega, el código descargado se ejecuta, pero no podrás lanzar ninguna función definida en este archivo desde tu código Javascript en respuesta al evento de carga de la página.Para más detalles: http://www.w3schools.com/tags/att_script_defer.asp

Mediante una función Javascript (válido para JS y CSS)

A continuación se muestran dos funciones Javascript que permiten cargar el archivo CSS o JS indicado como parámetro y, en el caso de archivos JS, ejecutar una función opcional una vez ha finalizado la descarga del archivo.Incluye estas funciones en el head de tu web (también es posible combinar ambas funciones e incluir un parámetro extra para indicar a la función si se desea cargar un archivo Javascript o una hoja de estilos).
  1: /**
  2:  * Carga no bloqueante de un archivo javascript.
  3:  * Parametros:
  4:  * - url: Url del archivo javascript a descargar
  5:  * - onLoad: function a ejecutar una vez descargado el script  
  6:  */

  7: function deferLoadScript(url, onLoad) {
  8:     // Crea un nuevo objecto "script" de forma dinámica
  9:     var s    = document.createElement("script");
 10:     s.type   = "text/javascript";
 11:     s.src    = url;
 12:     
 13:     // Define la función a ejecutar una vez finalizada la carga del script
 14:     var callOnLoad = function() {};
 15:     if ("function" == typeof(onLoad)) {
 16:         callOnLoad = function () {
 17:             onLoad();
 18:         }
 19:     }
 20:     
 21:     // Asocia la función callOnLoad al evento onLoad del script.
 22:     // En función del navegador utiliza un método u otro
 23:     if ("undefined" != typeof(s.addEventListener)) {
 24:     
 25:         // FF, Chrome, Safari, Opera
 26:         s.addEventListener("load",calltheCBcmn,false);
 27:         
 28:     } else {
 29:     
 30:         // IE 8+
 31:         function ieState() {
 32:             if ("loaded" == s.readyState){
 33:                 callOnLoad();
 34:             }
 35:         }
 36:         s.attachEvent("onreadystatechange", ieState);
 37:         
 38:     }
 39:     
 40:     // Incluye el script en el DOM del documento
 41:     document.getElementsByTagName("head")[0].appendChild(s);
 42: }

Para CSS:
  1: /**
  2:  * Carga no bloqueante de un archivo CSS.
  3:  * Parametros:
  4:  * - url: Url del archivo CSS a descargar  
  5:  */

  6: function deferLoadStyle(url) {
  7: 
  8:     // Crea un nuevo objecto "link" de forma dinámica
  9:     var s  = document.createElement("link");
 10:     s.href = url;
 11:     s.rel  = "stylesheet";
 12:     s.type = "text/css";
 13:     
 14:     // Incluye el CSS en el DOM del documento
 15:     document.getElementsByTagName("head")[0].appendChild(s);
 16:     
 17: }

Ejemplo básico de uso:
  1: <html>
  2:     <head>
  3:     <!-- CSS mínimo para mostrar la web -->
  4:     </head>
  5:     <body>
  6:         <!-- Código HTML -->
  7:         <!-- Archivos JS obligatorios -->
  8:         <script type="text/javascript">
  9:         // Carga no bloqueante del archivo extra.defer.js
 10:         deferLoadScript('/js/extra.defer.js', function() {
 11:             afterLoad(); // Función definida en el archivo extra.defer.js
 12:         });
 13:         // Carga no bloqueante del archivo extra.defer.css
 14:         deferLoadStyle('/css/extra.defer.css');
 15:         </script>
 16:     </body>
 17: </html>

Conclusión


Si quieres aumentar la velocidad de carga de tu web de una forma drástica y fácil, utiliza la carga no bloqueante de archivos, una vez aprendas a hacerlo, no usaras otro método.
Como observación, destacar que esta carga optimizada no debe usarse para cargar todos los archivos de estilo ni todos los archivos Javascript de tu web, utilízalo para cargar aquellos elementos extra; es decir, define un archivo de estilos con el mínimo de elementos para que tu web se vea correctamente, cárgalo normalmente y carga el resto de forma diferida. Haz lo mismo para tus archivos Javascript.
Un ejemplo de archivo que no debe cargarse de forma diferida es el framework JQuery.
¿Cómo optimizas tú la carga de tus archivos Javascript y CSS en tu web?