desenv-web-rp.com

Qual é a melhor maneira de carregar o Javascript em uma página para otimizar o desempenho?

Existe uma maneira de carregar meu JavaScript em uma página que o fará carregar mais rápido?

14
Jason

Há algumas coisas que tu podes fazer:

  1. Carregue o HTML e o CSS antes do javascript. Isso fornece ao navegador tudo o que é necessário para organizar e renderizar a página. Isso dá ao usuário a impressão de que a página é rápida. Coloque as tags ou blocos de script o mais próximo possível da tag do corpo de fechamento.

  2. Considere usar uma CDN. Se você estiver usando qualquer uma das bibliotecas populares como JQuery, muitas empresas (por exemplo, google, yahoo) operam CDNs gratuitas que você pode usar para carregar as bibliotecas.

  3. Carregar código de um arquivo externo em vez de um script incorporado. Isso dá ao navegador a oportunidade de armazenar em cache o conteúdo JS e não precisar carregá-lo. Carregamentos sucessivos de páginas serão mais rápidos.

  4. Ative a compactação Zip no servidor web.

O Yahoo possui uma ótima página de sugestões que podem ajudar a reduzir o tempo de carregamento da página.

14
Gareth Farrington

Além de Minifing, gziping e CDNing (nova palavra?). Você deve adiar o carregamento. Basicamente, o que isso faz é adicionar os scripts dinamicamente e impedir o bloqueio, permitindo downloads paralelos.

Existem muitas maneiras de fazer isso, essa é a que eu prefiro

<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 isso antes da tag body de fechamento e use o AttachScript para carregar todos os arquivos js.
Mais algumas informações aqui http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/

7
The Disintegrator

Convém observar também o modo como o Google carrega o Google 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 é considerado um tipo de script de "melhores práticas":
http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/

7
Jeff Atwood

Algumas pessoas do Google anunciaram um novo projeto de código aberto no Velocity 201 chamado Diffable . Diffable executa alguma mágica para publicar incrementalmente apenas as partes de JS, HTML e CSS que foram alteradas desde a versão armazenada no cache do usuário, em vez de enviar um novo arquivo inteiro quando uma nova versão é lançada.

Essa técnica é incrivelmente interessante e atualmente é mais eficaz (e vale o esforço) em sites em que você está usando uma grande base de código JavaScript com pequenas alterações frequentes no código. Isso se aplica especialmente a aplicativos como o Google Maps, que são submetidos a pelo menos m lançamento toda terça-feira e têm em média cerca de 100 novos lançamentos por ano. Também faz muito sentido, em geral, quando o armazenamento local HTML5 se torna mais difundido.

BTW, se você não viu Michael Jones do Google falar sobre mudanças (em um contexto geoespacial), vale a pena assistir todo o seu palestra na GeoWeb 2009 .

3
JasonBirch

Para atualizar uma pergunta. Penso que, na moderna, a forma de carregamento sem bloqueio não é mais necessária, o navegador fará isso por você.

Eu adicionei uma pergunta ao StackOverflow, adicionarei o conteúdo aqui também.

A única diferença é que o evento load será acionado um pouco antes, mas o carregamento dos arquivos em si permanecerá o mesmo. Também quero acrescentar que, mesmo que o onload seja acionado anteriormente com o script sem bloqueio, isso não significa que os arquivos JS foram acionados anteriormente. No meu caso, a configuração normal saiu melhor

Agora, primeiro os scripts, eles ficam assim:

<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 aqui é apenas um objeto que contém todos os URLs de todos os arquivos.

Eu executei 3 testes, eis os resultados:

Configuração normal

Page load with css in the head and javascript at the bottom

Esta é apenas a configuração normal, temos 4 arquivos css na cabeça e 3 arquivos css na parte inferior da página.

Agora não vejo nada bloqueando. O que eu vejo é que tudo está carregando ao mesmo tempo.

JS sem bloqueio

Page load with non-blocking javascript

Agora, para levar um pouco mais longe, eu fiz SOMENTE os arquivos js sem bloqueio. Isso com o script acima. De repente, vejo que meus arquivos css estão bloqueando a carga. Isso é estranho, porque não está bloqueando nada no primeiro exemplo. Por que o css está bloqueando repentinamente a carga?

Tudo sem bloqueio

Page load with everything non-blocking

Por fim, fiz um teste em que todos os arquivos externos são carregados de maneira não-bloqueante. Agora não vejo diferença no nosso primeiro método. Os dois parecem iguais.

Conclusão

Minha conclusão é que os arquivos já estão carregados de maneira não-bloqueante, não vejo necessidade de adicionar scripts especiais.

Ou estou faltando alguma coisa aqui?

Mais:

1
Saif Bechan