Eu fiz alguns projetos baseados na Web, mas não penso muito na sequência de carga e execução de uma página da Web comum. Mas agora eu preciso saber detalhes. É difícil encontrar respostas do Google ou do SO, por isso criei esta pergunta.
Uma página de amostra é assim:
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script src="abc.js" type="text/javascript">
</script>
<link rel="stylesheets" type="text/css" href="abc.css"></link>
<style>h2{font-wight:bold;}</style>
<script>
$(document).ready(function(){
$("#img").attr("src", "kkk.png");
});
</script>
</head>
<body>
<img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
<script src="kkk.js" type="text/javascript"></script>
</body>
</html>
Então, aqui estão as minhas questões:
- Como esta página é carregada?
- Qual é a sequência do carregamento?
- Quando o código JS é executado? (inline e externo)
- Quando o CSS é executado (aplicado)?
- Quando o $ (document) .ready é executado?
- O abc.jpg será baixado? Ou simplesmente faz o download do kkk.png?
Eu tenho o seguinte entendimento:
- O navegador carrega o html (DOM) primeiro.
- O navegador começa a carregar os recursos externos de cima para baixo, linha por linha.
- Se a
<script>
for atendido, o carregamento será bloqueado e espere até que o arquivo JS seja carregado e executado e continue. - Outros recursos (CSS / imagens) são carregados em paralelo e executados, se necessário (como CSS).
Ou é assim:
O navegador analisa o html (DOM) e obtém os recursos externos em uma matriz ou estrutura semelhante a uma pilha. Depois que o html é carregado, o navegador começa a carregar os recursos externos na estrutura em paralelo e a executar, até que todos os recursos sejam carregados. Em seguida, o DOM será alterado de acordo com o comportamento do usuário, dependendo do JS.
Alguém pode dar uma explicação detalhada sobre o que acontece quando você recebe a resposta de uma página html? Isso varia em diferentes navegadores? Alguma referência sobre esta questão?
Obrigado.
EDITAR:
Eu fiz um experimento no Firefox com o Firebug. E mostra como a seguinte imagem:
fonte
Respostas:
De acordo com sua amostra,
aproximadamente o fluxo de execução é o seguinte:
<script src="jquery.js" ...
jquery.js
é baixado e analisado<script src="abc.js" ...
abc.js
é baixado, analisado e executado<link href="abc.css" ...
abc.css
é baixado e analisado<style>...</style>
<script>...</script>
<img src="abc.jpg" ...
abc.jpg
é baixado e exibido<script src="kkk.js" ...
kkk.js
é baixado, analisado e executadoObserve que o download pode ser assíncrono e sem bloqueio devido a comportamentos do navegador. Por exemplo, no Firefox, existe essa configuração que limita o número de solicitações simultâneas por domínio.
Além disso, dependendo de o componente já ter sido armazenado em cache ou não, o componente pode não ser solicitado novamente em uma solicitação no futuro próximo. Se o componente tiver sido armazenado em cache, o componente será carregado a partir do cache, em vez da URL real.
Quando a análise é finalizada e o documento está pronto e carregado, os eventos
onload
são disparados. Assim, quandoonload
é acionado, o$("#img").attr("src","kkk.png");
é executado. Assim:$("#img").attr("src", "kkk.png");
kkk.png
é baixado e carregado em#img
O
$(document).ready()
evento é realmente o evento disparado quando todos os componentes da página estão carregados e prontos. Leia mais sobre o assunto: http://docs.jquery.com/Tutorials:Introducing_$ (document) .ready ()Editar - Esta parte elabora mais a parte paralela ou não:
Por padrão, e do meu entendimento atual, o navegador geralmente executa cada página de três maneiras: analisador de HTML, Javascript / DOM e CSS.
O analisador HTML é responsável por analisar e interpretar a linguagem de marcação e, portanto, deve poder fazer chamadas para os outros 2 componentes.
Por exemplo, quando o analisador se depara com esta linha:
O analisador fará três chamadas, duas para Javascript e uma para CSS. Primeiro, o analisador criará esse elemento e o registrará no espaço para nome DOM, juntamente com todos os atributos relacionados a esse elemento. Em segundo lugar, o analisador chamará para vincular o evento onclick a esse elemento específico. Por fim, ele fará outra chamada ao segmento CSS para aplicar o estilo CSS a esse elemento específico.
A execução é descendente e única encadeada. O Javascript pode parecer multiencadeado, mas o fato é que o Javascript é único encadeado. É por isso que, ao carregar o arquivo javascript externo, a análise da página HTML principal é suspensa.
No entanto, os arquivos CSS podem ser baixados simultaneamente, porque as regras CSS estão sempre sendo aplicadas - ou seja, os elementos são sempre repintados com as regras CSS mais recentes definidas - tornando-o desbloqueado.
Um elemento estará disponível apenas no DOM depois de ter sido analisado. Portanto, ao trabalhar com um elemento específico, o script é sempre colocado após ou dentro do evento onload da janela.
Script como este causará erro (no jQuery):
Porque quando o script é analisado, o
#mydiv
elemento ainda não está definido. Em vez disso, isso funcionaria:OU
fonte
<script>
vai bloquear outros componentes, certo? Alguma referência sobre as especificações para cada navegador?1) HTML é baixado.
2) HTML é analisado progressivamente. Quando uma solicitação de um ativo é alcançada, o navegador tenta fazer o download do ativo. Uma configuração padrão para a maioria dos servidores HTTP e a maioria dos navegadores é processar apenas duas solicitações em paralelo. O IE pode ser reconfigurado para baixar um número ilimitado de ativos em paralelo. Steve Souders conseguiu baixar mais de 100 solicitações em paralelo no IE. A exceção é que as solicitações de script bloqueiam solicitações de ativos paralelas no IE. É por isso que é altamente recomendável colocar todo o JavaScript em arquivos JavaScript externos e colocar a solicitação antes da tag do corpo de fechamento no HTML.
3) Depois que o HTML é analisado, o DOM é renderizado. O CSS é renderizado em paralelo com a renderização do DOM em quase todos os agentes do usuário. Como resultado, é altamente recomendável colocar todo o código CSS em arquivos CSS externos solicitados o mais alto possível na seção <head> </head> do documento. Caso contrário, a página será renderizada até a ocorrência da posição de solicitação de CSS no DOM e, em seguida, a renderização será iniciada novamente.
4) Somente depois que o DOM for renderizado completamente e as solicitações de todos os ativos da página forem resolvidas ou o tempo limite o JavaScript for executado a partir do evento onload. O IE7, e não tenho certeza sobre o IE8, não atinge o tempo limite dos ativos rapidamente se uma resposta HTTP não for recebida da solicitação de ativo. Isso significa que um ativo solicitado pelo JavaScript embutido na página, que é JavaScript gravado em tags HTML que não estão contidas em uma função, pode impedir a execução do evento onload por horas. Esse problema pode ser disparado se esse código embutido existir na página e falhar na execução devido a uma colisão de namespace que causa uma falha no código.
Das etapas acima, a que consome mais CPU é a análise do DOM / CSS. Se você deseja que sua página seja processada mais rapidamente, escreva CSS eficiente, eliminando instruções redundantes e consolidando instruções CSS no menor número possível de referências de elementos. Reduzir o número de nós na sua árvore DOM também produzirá renderização mais rápida.
Lembre-se de que cada recurso solicitado em seu HTML ou mesmo em CSS / JavaScript é solicitado com um cabeçalho HTTP separado. Isso consome largura de banda e requer processamento por solicitação. Se você deseja fazer com que sua página seja carregada o mais rápido possível, reduza o número de solicitações HTTP e reduza o tamanho do seu HTML. Você não está favorecendo a experiência do usuário calculando a média da ponderação da página em 180k somente a partir do HTML. Muitos desenvolvedores concordam com alguma falácia de que um usuário decide sobre a qualidade do conteúdo da página em 6 nanossegundos e, em seguida, elimina a consulta DNS do servidor e queima o computador se estiver insatisfeito. Portanto, eles fornecem a página mais bonita possível em 250k de HTML. Mantenha seu HTML curto e agradável para que um usuário possa carregar suas páginas mais rapidamente.
fonte
Abra sua página no Firefox e obtenha o complemento HTTPFox. Isso lhe dirá tudo o que você precisa.
Encontrei isso em archivist.incuito:
http://archivist.incutio.com/viewlist/css-discuss/76444
fonte
Se você está perguntando isso porque deseja acelerar o seu site, consulte a página do Yahoo sobre Práticas recomendadas para acelerar o seu site . Possui muitas práticas recomendadas para acelerar o seu site.
fonte
AFAIK, o navegador (pelo menos Firefox) solicita todos os recursos assim que o analisa. Se encontrar uma tag img, solicitará a imagem assim que a tag img for analisada. E isso pode acontecer antes mesmo de receber a totalidade do documento HTML ... ou seja, ele ainda pode estar baixando o documento HTML quando isso acontecer.
Para o Firefox, existem filas de navegadores que se aplicam, dependendo de como elas são definidas em about: config. Por exemplo, ele não tentará baixar mais de 8 arquivos de uma vez no mesmo servidor ... os pedidos adicionais serão colocados na fila. Eu acho que existem limites por domínio, limites de proxy e outras coisas, que estão documentados no site da Mozilla e podem ser configurados em about: config. Eu li em algum lugar que o IE não tem esses limites.
O evento pronto para jQuery é acionado assim que o documento HTML principal é baixado e é analisado pelo DOM. Em seguida, o evento de carregamento é acionado depois que todos os recursos vinculados (CSS, imagens etc.) também foram baixados e analisados. Isso fica claro na documentação do jQuery.
Se você deseja controlar a ordem na qual tudo é carregado, acredito que a maneira mais confiável de fazer isso é através do JavaScript.
fonte
O Dynatrace AJAX Edition mostra a sequência exata de carregamento, análise e execução de páginas.
fonte
A resposta escolhida parece não se aplicar a navegadores modernos, pelo menos no Firefox 52. O que observei é que as solicitações de carregamento de recursos como css, javascript são emitidas antes que o analisador HTML atinja o elemento, por exemplo
O que descobri que a hora de início das solicitações para carregar recursos css e javascript não estava sendo bloqueada. Parece que o Firefox tem uma verificação em HTML e identifica os principais recursos (o recurso img não está incluído) antes de começar a analisar o HTML.
fonte