Existem 3 diferentes “janelas de tempo” que acontecem durante um requisição web em que é possível carregar e executar JavaScript. Essas “janelas” são delineadas pelos eventos DOMContentLoaded e OnLoad. É possível carregar scripts antes de DOMContentLoaded
, depois de DOMContentLoad
e depois de OnLoad
. Mas, antes de adentrar nos detalhes sobre como funciona o loading de JavaScript, o que são esses 2 eventos e quando eles são realmente desencadeados?
Os eventos
O evento DOMContentLoaded é disparado quando o DOM (Document Object Model) está pronto. O que isso significa é que a API para interagir com conteúdo, estilo e estrutura de uma página está pronta para receber solicitações de seu código. Em geral, isso significa que o texto, HTML e CSS estão prontos – mas não é tão simples assim. Dependendo do navegador, versão do HTML e onde as tags de folhas de estilo estão, em relação às de script, o CSS não pode ser renderizado no momento em que esse evento é acionado.
Felizmente, há uma maneira segura e de alto desempenho para garantir que o CSS é carregado primeiro: é tão simples como colocar as folhas de estilo externas no cabeçalho e os JavaScripts externos no rodapé. Esta abordagem faz com que o JS execute somente depois das folhas de estilo externas e corpo do HTML já terem sido carregados. Basicamente, isso significa que, se se está colocando folhas de estilo no cabeçalho e JSs no rodapé, o DOM irá carregar todo o conteúdo, estrutura e estilo antes do evento DOMContentLoaded
ser acionado. E isso é uma boa coisa!
O evento onLoad é disparado quando toda a página foi carregada – este é momento em que o carregador na barra de título do seu navegador para de girar. Neste ponto, todos os scripts e folhas de estilo terminaram de carregar e foram executados e todas as imagens foram baixadas e exibidas.
Carregando JavaScript
Então, como é possível “pegar o gancho” de cada um desses eventos e, mais importante, quando se deve usar cada um deles? Para examinar os diferentes “ganchos”, veja esta página HTML simples e o resultado que ela produz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<!DOCTYPE html> <body> <script src="jquery.min.js"></script> <script src="external.js"></script> <script type='text/javascript'> //<![CDATA[ $.getScript('ajax.js'); $(document).ready(function(){ console.log('DOM Loaded (DOMContentLoaded)'); $('head').append('<script src="dom.js"></script>'); $.getScript('dom_ajax.js'); }); $(window).load(function(){ console.log('Page Loaded (OnLoad)'); $.getScript('page_ajax.js'); }); //]]> </script> </body> |
Examinando o console, é possível ver a seguinte ordem de execução:
1 2 3 4 5 6 7 |
external.js Loaded and Executed DOM Loaded (DOMContentLoaded) dom.js Loaded and Executed Page Loaded (OnLoad) ajax.js Loaded and Executed dom_ajax.js Loaded and Executed page_ajax.js Loaded and Executed |
A partir dessa saída, é possível inferir 3 coisas:
- JavaScript externo (
external.js
) é carregado antes deDOMContentLoaded
- JavaScript externo inserido no HTML durante o callback de
DOMContentLoaded
é carregado antes deOnLoad
- Requisições AJAX não atrasam
DOMContentLoaded
ouOnLoad
, independentemente de quando são iniciadas (ajax.js
,dom_ajax.js
epage_ajax.js
)
Antes de DOMContentLoaded
Primeiro, tanto JavaScript inline, quanto externo (external.js
), são carregados e executados imediatamente, independentemente do DOM estar pronto ou a página ter sido carregada.
Isso pode parecer óbvio, mas é necessário para executar este código antes de DOMContentLoaded
para que seja possível, realmente, pegar o gancho do evento. A melhor maneira de pensar nesse JavaScript é como se fosse um setup. No entanto, não se deve manipular o DOM uma vez que este ainda não está pronto – é preciso configurar os retornos de chamada e, em seguida, sair do caminho para que o resto da página possa ser carregado rapidamente.
Depois de DOMContentLoaded
Esses scripts (dom.js
) são executados quando o DOM está pronto para ser manipulado. É onde se deve colocar qualquer código que altere o visual da página, já que esse é o primeiro momento em que a manipulação de DOM é possível e é executado antes que a página seja exibida.
Isso é uma coisa boa, porque ninguém quer os elementos da página pulando e mudando de estilo depois que eles já estão visíveis para o visitante.
Depois de OnLoad
Esses scripts (requisições AJAX e qualquer coisa no callback de window.load
) são executados depois que o carregamento da página tenha sido concluído e o visitante possa visualizar todo o documento. Esse é um ótimo lugar para carregar scripts de longa duração e scripts que não alteram o visual da página. Alguns exemplos incluem bibliotecas de análise e relatórios de código ou dados que podem ser usados mais tarde ou; que possa ser pré-obtida para o visitante.
Algo mais concreto: Google Maps carrega todas as “pecinhas de mapa” usando AJAX para que o carregamento da página não seja interrompida.
Conclusão sobre DOMContentLoaded e OnLoad
Com isso, você viu como loading de JavaScript funciona e um pouco mais sobre DOMContentLoaded
e OnLoad
. No entanto, há muito mais para estudar, já que conhecer mais a fundo para o que servem e como se valer destes eventos é uma garantia de que você está preocupado com o desempenho do site e tem uma atenção especial com o funcionamento das coisas, propriamente dito.
Tente manter esse processo de carregamento da página em mente ao escrever código JavaScript, já que a simples colocação de código em lugares diferentes pode levar a grandes ganhos no tempo de carregamento da página e percepção de carregamento, em geral.