Modernizr.load() e o carregamento condicional de bibliotecas Javascript y CSS

O método load() de Modernizr serve para carregar bibliotecas Javascript dependendo das capacidades do navegador.

Por Miguel Angel Alvarez - Tradução de Celeste Veiga


Publicado em: 20/12/11
Valorize este artigo:
Até agora no Manual de Modernizr vimos muitas coisas simples, que nos podem ajudar a aumentar o grau de compatibilidade de nossa web a diferentes navegadores e dispositivos. Os conhecimentos que você poderá ter adquirido até o momento servem tanto para designers como para programadores, no entanto as bibliotecas possuem alguns usos interessantes que ainda não vimos, que ajudarão sobretudo os desenvolvedores HTML5 e os programadores Javascript.

Nesse sentido, começamos uma série de artigos que nos detalharão alguns dos pontos mais interessantes que nos oferecem estas bibliotecas, começando nesta ocasião com uma introdução ao método Modernizr.load(), um gestor condicional de carregamento de bibliotecas Javascript e CSS.

Modernizr.load() está baseado em algumas bibliotecas chamadas yepnope.js que servem basicamente para carregar bibliotecas apenas quando os usuários as necessitam. Trata-se de um simples método que permite avaliar uma condição e dizer que bibliotecas carregar quando se cumpra e quais quando não.

As condições podem ser as propriedades que nos oferece Modernizr, de modo que carreguemos determinadas bibliotecas somente nos casos em que se necessitem. Por exemplo, pensemos que estamos fazendo uma página baseada no API Local Storage do HTML5. Com Modernizr podemos saber se o navegador do usuário oferece suporte a esse API, mediante a propriedade:

Modernizr.localstorage

Avaliar essa propriedade, para fazer umas coisas ou outras com Javascript, é bastante simples, tal como vimos no artigo sobre Detectar as capacidades de navegadores com Javascript.
Agora bem, se desejamos carregar uns recursos ou outros no navegador dependendo dela, o método Modernizr.load() nos poderá economizar algo de código fonte e de passo acelerar nossa página em algumas ocasiões.

Quando em CriarWeb.com publicamos a apresentação inicial de Modernizr falamos dos Polyfills e explicamos que existiam bibliotecas para implementar quase todas as características do HTML5 em navegadores que não as suportavam de maneira nativa. Essas bibliotecas são os mencionados Polyfills e as podemos carregar de maneira condicional por meio de Modernizr.load().

Voltando ao exemplo do Local Storage, com Modernizr.load() podemos indicar aos navegadores que não suportem esse API que carreguem o Polyfill Storage, de modo que se possa utilizar essa característica do HTML 5 neles também.

Sintaxe de Modernizr.load()

Agora que já podemos ter uma idéia mais ou menos exata do que pode ser feito com Modernizr.load(), vamos repassar um pouco sua sintaxe.

Nota: Modernizr.load() é um acréscimo a Modernizr de download opcional. Na verdade, se você está utilizando a versão de desenvolvimento de Modernizr não se inclui este método, de modo que você teria que fazer um download para produção que o incluísse. Da página de download de Modernizr você verá que no quadro "Extra" existem diversos acréscimos entre os quais você encontrará a mencionada função Modernizr.load.

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

No código anterior podemos ver a chamada ao método load. Nela indicamos várias propriedades em notação de objeto:

  • test: é a avaliação que vai ser realizada para saber se temos suporte a uma ou a outra capacidade no navegador.
  • yep: onde indicamos as bibliotecas que devem ser carregadas no caso de que a avaliação anterior dê positivo. Neste caso, quando o navegador é compatível com Local Storage del HTML5, se carregará uma única biblioteca chamada 'existe_suporte_nativo.js'.
  • nope: onde se indica a biblioteca/s que queremos carregar quando a avaliação dê negativo. No exemplo anterior, no caso de que o navegador não tenha suporte a Local Storage, se carregaria a biblioteca 'storage-polyfill.js' e ademais a declaração de estilos 'estilos-polyfill.css'.
Como vimos, a sintaxe e uso do método load() é bastante simples, mas ainda se poderia personalizar um pouco mais este script para fazer mais coisas úteis.

Carregamento de bibliotecas para os casos positivos e negativos:
Também podemos especificar os arquivos Javascript ou CSS que queremos carregar quando se cumpra determinada avaliação e quando não se cumpra. Para tanto, simplesmente criamos outra propriedade no parâmetro passado a load(), chamada "both".

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

Neste caso serão avaliados se o navegador dispõe de suporte para múltiplos fundos com CSS3 e para as propriedades de opacidade. Em caso negativo se carregaria a biblioteca "polyfills-css,js" e tanto em caso positivo como no negativo (ou seja, em todos os navegadores) se carregaria a biblioteca "outras-coisas.js".

Fazer coisas depois do carregamento das bibliotecas:
Em algumas ocasiões queremos fazer algum tipo de ação, mas não queremos executá-la até não terem sido carregadas determinadas bibliotecas. Para isso, pode ser implementada uma função na propriedade complete, que só será executada quando as bibliotecas tenham sido carregadas.

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

Neste caso se avalia se existe suporte ao API de geolocalização. Em caso positivo se carregam uns scripts ('geo-extras.js'), em caso negativo outros ('geo-polyfill.js') e para ambos casos se carrega outra biblioteca ('minhageolocalizacao.js'). O interessante neste exemplo é o método seguinte, baixo o nome de complete, onde se ha atribuído uma função que será executada só depois de haver carregado todas as bibliotecas que corresponda em cada caso. Nessa função podemos colocar código que necessite dessas bibliotecas com total segurança, já que saberemos seguramente que seu carregamento terá sido realizado anteriormente a sua execução da função complete.

Carregamento no condicional de bibliotecas
Com Modernizr.load() também podemos carregar bibliotecas de maneira incondicional, ou seja, sem avaliar previamente nenhuma condição. Para tanto utilizamos a propriedade load. Agora vemos um método copiado diretamente do tutorial de Modernizr.load() que está na documentação destas bibliotecas.

Eu o copiei porque me parece um caso excelente de uso desta funcionalidade. Trata-se de um script que se traz por CDN à biblioteca jQuery mas que, se houve algum problema com tal biblioteca, carrega jQuery diretamente de uma cópia do framework em nosso 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');
      }
   }
});

Neste exemplo se carrega jQuery a partir do CDN de Google APIs. Utilizamos a propriedade "load", logo não existe nenhuma avaliação, senão que simplesmente se carrega essa biblioteca independentemente do navegador do usuário. Em seguida se utiliza complete para especificar uma função a ser a executada quando se termina o carregamento das bibliotecas. Nessa função se avalia !window.jQuery. Se jQuery não tivesse sido carregado, essa avaliação nos levaria ao carregamento do framework diretamente de uma rota a partir de nosso próprio servidor, utilizando de novo Modernizr.load().

Carregamento de vários pacotes de bibliotecas de maneira sequencial:
Por último vamos mostrar como realizar vários blocos de carregamento de bibliotecas dentro de uma única chamada a modernizr.load(), o que nos servirá quando queiramos carregar condicionalmente diversos conjuntos de bibliotecas dependendo de várias avaliações independentes. Todos esses blocos serão indicados em um array e serão executados um atrás do outro, e por isso até que não sejam carregadas as bibliotecas do primeiro bloco, não se passará ao seguinte.

Modernizr.load([
   //Primeiro bloco
   {
      test : Modernizr.fontface,
      nope : ['fontes-css.js', 'outros-estilos.css']
   },
   //Segundo bloco
   {
      test : Modernizr.audio,
      nope : 'suporte-audio.js',
      both : 'meu_fio_musical.js',
      complete : function () {
         iniciarMusica();
      }
   },
   //terceiro bloco
   'script-estatisticas.js'
]);

Neste exemplo temos três blocos.

  1. Primeiro se verá se temos suporte para @font-face, carregando um arquivo Javascript e outro CSS em caso negativo.
  2. A seguir se verá se temos suporte ao áudio de HTML5, carregando bibliotecas que nos ofereçam compatibilidade quando não se tenha e carregando uma biblioteca para implementar meu som de fundo. Quando todas essas bibliotecas estejam carregadas, se chama a função iniciarMusica(), que iniciaria o som.
  3. Por último se carregará o script para a contabilidade das estatísticas nesta página. Se observarmos, o carregamento deste script se realiza diretamente, sem avaliar condição alguma. Para isso simplesmente indicamos o nome da biblioteca a ser carregada. Isto é perfeitamente possível no método Modernizr.load().
O interessante deste método de carregamento é que se realiza passo a passo, por isso podemos deixar para o final os scripts que menos importância tenham. Neste exemplo, tirado também da documentação de Modernizr, temos que, no último bloco se carrega o script de estatísticas, que é o menos importante. Assim saberemos com certeza que a contabilidade desta visita do usuário se realizará só quando já se tenham terminado de carregar outras bibliotecas mais importantes.

Cabe destacar também, segundo comentado na documentação, que este modo de carregamento sequencial de bibliotecas, apesar de ter que esperar o completo descarregamento de um bloco antes de começar o carregamento do seguinte, não suporá uma redução da velocidade do site com respeito a se todas as bibliotecas foram descarregadas em paralelo. Inclusive em determinadas ocasiões dizem que poderia aumentar a velocidade.

O que está claro é que, graças a Modernizr, podemos facilmente discriminar entre navegadores e carregar somente aquelas bibliotecas que nosso navegador necessite, em vez de carregá-las todas e depois ver se realmente eram necessárias. Sem dúvida poderíamos fazer nossas próprias validações para averiguar se são necessárias e em seguida carregá-las por meio de nossos próprios scripts, mas dificilmente vamos poder realizar as coisas por nós mesmos mais rápido e melhor do que propõe Modernizr.load().

No artigo seguinte apresentaremos um exemplo completo de carregamento de um pollyfill para compatibilidade com Canvas del HTML 5, condicionalmente por meio de Modernizr.load(), de modo que só se invoque quando o navegador não disponha de suporte nativo para canvas.






Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor

Home | Sobre nós | Copyright | Anuncie | Entrar em contato