Modernizr.load() y la carga condicional de librerías Javascript y CSS

  • Por
El método load() de Modernizr sirve para cargar librerías Javascript dependiendo de las capacidades del navegador.
Hasta ahora en el Manual de Modernizr hemos visto muchas cosas sencillas, que nos pueden ayudar a aumentar el grado de adaptabilidad de nuestra web a distintos navegadores y dispositivos. Los conocimientos que habrás podido adquirir hasta el momento sirven tanto para diseñadores como para programadores, sin embargo las librerías todavía tienen algunos usos interesantes que no hemos visto, que ayudarán sobre todo a los desarrolladores HTML5 y a los programadores Javascript.

En ese sentido, comenzamos una serie de artículos que nos detallarán algunos de los puntos más interesantes que nos ofrecen estas librerías, comenzando en esta ocasión con una introducción al método Modernizr.load(), un gestor condicional de carga de librerías Javascript y CSS.

Modernizr.load() está basado en unas librerías llamadas yepnope.js que sirven básicamente para cargar librerías solo cuando los usuarios las necesitan. Se trata de un sencillo método que permite evaluar una condición y decir qué librerías cargar cuando se cumpla y cuáles cuando no.

Las condiciones pueden ser las propiedades que nos ofrece Modernizr, de modo que carguemos determinadas librerías solamente en los casos en los que se necesiten. Por ejemplo, pensemos en que estamos haciendo una página basada en el API Local Storage del HTML5. Con Modernizr podemos saber si el navegador del usuario ofrece soporte a ese API, mediante la propiedad:

Modernizr.localstorage

Evaluar esa propiedad, para hacer unas cosas u otras con Javascript, es bastante sencillo, tal como vimos en el artículo sobre Detectar las capacidades de navegadores con Javascript.
Ahora bien, si deseamos cargar unos recursos u otros en el navegador dependiendo de ella, el método Modernizr.load() nos podrá ahorrar algo de código fuente y de paso acelerar nuestra página en algunas ocasiones.

Cuando en DesarrolloWeb.com publicamos la presentación inicial de Modernizr os hablamos de los Polyfills y explicamos que existían librerías para implementar casi todas las características del HTML5 en navegadores que no las soportaban de manera nativa. Esas librerías son los mencionados Polyfills y las podemos cargar de manera condicional por medio de Modernizr.load().

Volviendo al ejemplo del Local Storage, con Modernizr.load() podemos indicar a los navegadores que no soporten ese API que carguen el Polyfill Storage, de modo que se pueda utilizar esa característica del HTML 5 en ellos también.

Sintaxis de Modernizr.load()

Ahora que ya podemos tener una idea más o menos exacta de lo que se puede hacer con Modernizr.load(), vamos a repasar un poco su sintaxis.

Nota: Modernizr.load() es un añadido a Modernizr de descarga opcional. De hecho, si estás utilizando la versión de desarrollo de Modernizr no se incluye este método, por lo que tendrías que hacer una descarga para producción que sí lo incluya. Desde la página de download de Modernizr verás que en el recuadro "Extra" existen diversos añadidos entre los que encontrarás la mencionada función Modernizr.load.

Modernizr.load({
   test: Modernizr.localstorage,
   yep : 'existe_soporte_nativo.js',
   nope: ['storage-polyfill.js', 'estilos-polyfill.css']
});

En el código anterior podemos ver la llamada al método load. En ella indicamos varias propiedades en notación de objeto:

  • test: es la evaluación que se va a realizar para saber si tenemos soporte a una u otra capacidad en el navegador.
  • yep: donde indicamos las librerías que deben cargarse en caso que la evaluación anterior de positivo. En este caso, cuando el navegador es compatible con Local Storage del HTML5, se cargará una única librería llamada 'existe_soporte_nativo.js'.
  • nope: donde se indica la librería/s que queremos cargar cuando la evaluación de negativo. En el ejemplo anterior, en caso que el navegador no tenga soporte a Local Storage, se cargaría la librería 'storage-polyfill.js' y además la declaración de estilos 'estilos-polyfill.css'.
Como hemos visto, la sintaxis y uso del método load() es bastante sencilla, pero aun se podría personalizar un poco más este script para hacer más cosas útiles.

Cargar de librerías para los casos positivos y negativos:
También podemos especificar los archivos Javascript o CSS que queremos cargar cuando se cumpla determinada evaluación y cuando no se cumpla. Para ello simplemente creamos otra propiedad en el parámetro pasado a load(), llamada "both".

Modernizr.load({
   test: Modernizr.multiplebgs && Modernizr.opacity,
   nope: 'polyfills-css.js',
   both: 'otras-cosas.js'
});

En este caso se evaluarán si el navegador dispone de soporte para múltiples fondos con CSS3 y para las propiedades de opacidad. En caso negativo se cargaría la librería "polyfills-css,js" y tanto en caso positivo como en el negativo (es decir, en todos los navegadores) se cargaría la librería "otras-cosas.js".

Hacer cosas después de la carga de las librerías:
En ocasiones queremos hacer algún tipo de acción, pero no queremos ejecutarla hasta no haber sido cargadas determinadas librerías. Para ello se puede implementar una función en la propiedad complete, que solamente se ejecutará cuando las librerías hayan sido cargadas.

Modernizr.load({
   test: Modernizr.geolocation,
   yep : 'geo-extras.js',
   nope: 'geo-polyfill.js',
   both: 'migeolocalizacion.js',
   complete: function(){
      inicializar-geolocalizacion();
   }
});

En este caso se evalúa si existe soporte al API de geolocalización. En caso positivo se cargan unos scripts ('geo-extras.js'), en caso negativo otros ('geo-polyfill.js') y para ambos casos se carga otra librería ('migeolocalizacion.js'). Lo interesante en este ejemplo es el método siguiente, bajo el nombre de complete, donde se ha asignado una función que se ejecutará solo después de haber cargado todas las librerías que corresponda en cada caso. En esa función podemos colocar código que necesite de esas librerías con total seguridad, ya que sabremos seguro que su carga se habrá realizado anteriormente a su la ejecución de la función complete.

Carga no condicional de librerías
Con Modernizr.load() también podemos cargar librerías de manera incondicional, es decir, sin evaluar previamente ninguna condición. Para ello utilizamos la propiedad load. Ahora vemos un método copiado directamente del tutorial de Modernizr.load() que está en la documentación de estas librerías.

Lo he copiado porque me parece un caso excelente de uso de esta funcionalidad. Se trata de un script que se trae por CDN la librería jQuery pero que, si hubo algún problema con dicha librería, carga jQuery directamente de una copia del framework en nuestro servidor local.

Modernizr.load({
   load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.js',
   complete: function () {
      if ( !window.jQuery ) {
         Modernizr.load('js/jquery-1.6.3.min.js');
      }
   }
});

En este ejemplo se carga jQuery desde el CDN de Google APIs. Utilizamos la propiedad "load", luego no existe ninguna evaluación, sino que simplemente se carga esa librería independientemente del navegador del usuario. Luego se utiliza complete para especificar una función a ejecutar cuando se termina la carga de las librerías. En esa función se evalúa !window.jQuery. Si jQuery no se hubiera cargado, esa evaluación nos llevaría a la carga del framework directamente de una ruta desde nuestro propio servidor, utilizando de nuevo Modernizr.load().

Carga de varios paquetes de librerías de manera secuencial:
Por último vamos a mostrar cómo realizar varios bloques de carga de librerías dentro de una única llamada a modernizr.load(), lo que nos servirá cuando queremos cargar condicionalmente diversos conjuntos de librerías dependiendo de varias evaluaciones independientes. Todos esos bloques se indicarán en un array y se ejecutarán uno detrás de otro, por lo que hasta que no se carguen las librerías del primer bloque, no se pasará al siguiente.

Modernizr.load([
   //Primer bloque
   {
      test : Modernizr.fontface,
      nope : ['fuentes-css.js', 'otros-estilos.css']
   },
   //Segundo bloque
   {
      test : Modernizr.audio,
      nope : 'soporte-audio.js',
      both : 'mi_hilo_musical.js',
      complete : function () {
         iniciarMusica();
      }
   },
   //tercer bloque
   'script-estadisticas.js'
]);

En este ejemplo tenemos tres bloques.

  1. Primero se verá si tenemos soporte para @font-face, cargando un archivo Javascript y otro CSS en caso negativo.
  2. Luego se verá si tenemos soporte al audio de HTML5, cargando librerías que nos ofrezcan compatibilidad cuando no se tenga y cargando una librería para implementar mi sonido de fondo. Cuando todas esas librerías estén cargadas, se llama a la función iniciarMusica(), que iniciaría el sonido.
  3. Por último se cargará el script para la contabilidad de las estadísticas en esta página. Si nos fijamos la carga de este script se realiza directamente, sin evaluar condición alguna. Para ello simplemente indicamos el nombre de la librería a cargar. Esto es perfectamente posible en el método Modernizr.load().
Lo interesante de este método de carga es que se realiza paso a paso, por lo que podemos dejar para el final los scripts que menos importancia tienen. En este ejemplo, sacado también de la documentación de Modernizr, tenemos que en el último bloque se carga el script de estadísticas, que es lo menos importante. Así sabremos seguro que la contabilidad de esta visita del usuario se realizará solo cuando ya han terminado de cargarse otras librerías más importantes.

Cabe destacar también, según comentan en la documentación, que este modo de carga secuencial de librerías, a pesar de tener que esperar a la completa descarga de un bloque antes de comenzar la carga del siguiente, no supondrá un descenso de la velocidad del sitio con respecto a si todas las librerías fueran descargadas en paralelo. Incluso en determinadas ocasiones dicen que podría aumentar la velocidad.

Lo que está claro es que, gracias a Modernizr, podemos fácilmente discriminar entre navegadores y cargar solamente aquellas librerías que nuestro navegador necesite, en vez de cargarlas todas y luego ver si realmente se necesitaban. Sin duda podríamos hacer nuestras propias validaciones para averiguar si se necesitan y luego cargarlas por medio de nuestros propios scripts, pero difícilmente vamos a poder realizar las cosas por nosotros mismos más rápido y mejor de lo que propone Modernizr.load().

En el siguiente artículo presentaremos un ejemplo completo de carga de un pollyfill para compatibilidad con Canvas del HTML 5, condicionalmente por medio de Modernizr.load(), de modo que solo se invoque cuando el navegador no disponga de soporte nativo a canvas.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

equiman

19/9/2012
De donde se descarga?
Donde se descarga storage-polyfill.js y estilos-polyfill.cs o estan incluidos dentro de Modernizr?

jeffsantillan

04/11/2012
Muchisimas Gracias
Muchas gracias por tan excelente manual, ya lo descargue, pero al parecer habra un siguiente articulo. Saludos.

cristian

13/10/2017
modernizr.load
hola ahora en el modernizr del sitio oficial no me sale para cargar el modernizr.load, por lo siguiente en la consola me sale que modernizr.load no es una función, como lo puedo solucionar?