Carregamento assíncrono de jQuery em HTML5

Depois de ter escrito sobre o Page Speed comecei à procura de uma maneira para carregar o jQuery de forma diferida, mas encontrei vários problemas.

Após várias horas perdidas cheguei a uma solução eficaz.

Carregamento diferido de Javascript

O carregamento forma assíncrona de Javascript em HTML5 é simples, basta adicionar a propriedade async à tag <script> e está feito. Se o browser não suportar este método simplesmente ignora a propriedade e faz o carregamento de forma normal.

1
<script src="script.js" async></script>

Mas no meu caso eu tenho o jQuery separado das minhas funções e o ficheiro mais pequeno de funções carrega primeiro que o jQuery devolvendo um erro. Uma ideia é juntar tudo num só ficheiro, mas eu estou a carregar o jQuery a partir do Google.

O que posso fazer aqui é usar a propriedade defer que faz o carregamento de forma assíncrona mas executa os scripts pela ordem que são chamados, independentemente do que carregar primeiro.

1
2
<script src="jquery.js" defer></script>
<script src="script.js" defer></script>

Óptimo, se o ficheiro script.js carregar primeiro o browser vai esperar pelo ficheiro jquery.js para ser executado, e se este não suportar o defer faz o carregamento normal. Isto é a teoria, na prática o Internet Explorer executa o que carregar primeiro e curiosamente o Chrome não suporta o defer que existe desde o IE4, mas suporta o async :-|

Carregar o jQuery de forma diferida

O ficheiro de funções precisa do jQuery, portanto é preciso verificar se o jQuery está carregado antes de o executar. Tentei várias formas e a melhor é criar uma função que se chama a si própria para verificar se o jQuery está disponível.

1
2
3
4
5
6
7
8
9
10
function init() {
  if (window.jQuery) {

    // Código dependente do jQuery fica aqui

  } else {
    window.setTimeout(init, 100);
  }
}
init();

Com esta função a substituir o típico $(function() {}); podemos carregar o jQuery de forma assíncrona sem qualquer problema.

Browsers sem suporte a async

Nos browsers sem suporte a async os scripts vão ser descarregados normalmente, portanto é aconselhável continuar a colocar este código antes de fechar o <body>.

Outra maneira é usar uma função como o Google Analytics ou o Facebook usa para carregar o código depois o window.onload mas pelos testes que efectuei, apesar do carregamento parecer mais rápido com o window.onload a ocorrer mais cedo, no total a página demora mais a carregar, tanto como chamar os scripts normalmente sem qualquer atributo. O lado positivo é que a funcionalidade é compatível com XHTML ou HTML4.

Velocidade de carregamento

Efectuei alguns testes de carregamento sem cache com 4 métodos e os resultados foram os seguintes:

Teste de carregamento diferido de Javascript

Os testes foram efectuados no Site dos Provérbios que está construído em HTML5 e usa jQuery. Achei curioso o facto de o carregamento dinâmico por Javascript (usado pelo Google Analytics) tornar mais lento o carregamento do site do que fazer um carregamento normal com uma chamada ao script sem qualquer atributo adicional, mas faz sentido porque existe uma chamada por AJAX após o site carregar.

Tanto o defer como o async tiveram o mesmo resultado, tendo eu optado pelo último por questões de compatibilidade com mais browsers. No entanto o defer faz mais sentido porque teoricamente respeita a hierarquia definida, mas na prática isso não acontece.

 
Copyright © 1985 - 2017 Eduardo Maio. Alguns direitos reservados.
eduardomaio.net - Às vezes mais valia ser Agricultor do que Programador
Ao navegar no blog eduardomaio.net está a concordar com os termos legais e de privacidade.