O mais importante para o desenvolvedor do Frontend é o módulo de exibição do navegador, que também é o Rendering Engine (a seguir denominado RE).
Neste artigo, quero pegar uma página simples e seguir todas as etapas, juntamente com o RE, do recebimento do primeiro byte para desenhar o conteúdo na tela. Como sempre, usarei o navegador Chrome.
Primeiro, vamos ver em que outros módulos o navegador consiste, para entender com o que o ER interage.
Considere o esquema:
Figura 1Interface do usuário, interface do usuário (a seguir denominada interface do usuário) - uma API externa do navegador para o usuário: barra de endereços, navegação, menu, favoritos, botões 'atualizar' e 'casa'.
O mecanismo do navegador, o mecanismo do navegador (doravante BE), é uma camada entre a interface do usuário e o módulo de exibição.
Módulo de exibição do mecanismo de renderização . Vamos analisá-lo com mais detalhes posteriormente.
Componentes de rede, a rede é responsável por solicitações de rede. O ER recebe dados da rede. Os dados são recebidos em porções de 8 KB e o ER não espera até que todos os dados cheguem, eles começam a processá-los conforme chegam.
O módulo JS Interpreter é responsável por interpretar e executar o script.
O back -
end da interface do usuário é usado para renderizar elementos gráficos e widgets básicos, como janelas e caixas de combinação. Um exemplo simples de uma janela de alerta ou prompt.
Um repositório de dados é um cookie, indexDB e outros repositórios de navegadores.
Agora que sabemos em um nível básico em que consiste o navegador, podemos passar para o componente em que estamos interessados - o Rendering Engine.
É mais fácil e rápido entender com um exemplo específico, então vamos dar uma página html simples com um arquivo css e js externo (o script está conectado ao atributo async, analisaremos o porquê). E vamos ver como o RE os processa e quais etapas são executadas antes de vermos o conteúdo que precisamos na tela.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="./style.css"></link> <title>Document</title> </head> <body> <div>Hello Habr!</div> <div>I'am Rendering Engine</div> <script async src="./script.js"></script> </body> </html>
(function() { window.addEventListener('load', () => { console.log('all resources were loaded'); }); })();
* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Helvetica, sans-serif; line-height: 1.5; background-color: #9BD4F4; padding: 16px; }
Para fazer isso, acesse o Chrome DevTools, abra a guia desempenho e inicie o processo. Após recarregar a página e analisar o que aconteceu, observamos a seguinte figura:
Figura 2Na guia Rede - a sequência de download de dados pela rede (caixa azul - index.html).
Na guia Tempos, há marcas quando ocorreram eventos DCL (DOM Content Loaded, FP - primeira pintura com conteúdo, FMP - primeira pintura com significado, L - load). Vamos ver o que são esses eventos.
DOMContentLoaded - o navegador carregou o HTML, o analisou e criou uma árvore DOM. Este evento é acionado no documento, você pode se inscrever facilmente e trabalhar com o DOM via JavaScript (em nosso script, não poderemos assinar o evento DOMContentLoaded, pois ocorreu antes da análise do script, veja a
figura ).
Além disso, o DOMContentLoaded tem várias nuances:
- Se o script estiver conectado sem tags assíncronas / adiadas (de forma síncrona), ele bloqueará a análise de HTML. No entanto, os navegadores usaram recentemente a análise especulativa e, nesses casos, ainda fazem o download desse script com antecedência e fazem a análise. Isso não afeta a estrutura da árvore DOM, mas permite reduzir o tempo de trabalho do ER. A figura abaixo mostra como o tempo do DCL e de todos os outros eventos de renderização aumenta com a conexão de script síncrona
- O bloqueio de análise (você adivinhou) pode ser contornado com atributos async / defer, que permitem continuar analisando o HTML sem esperar o download e a execução do script
- Além disso, o evento DCL pode ser atrasado devido a estilos de carregamento. Durante a execução do script, o navegador pode ver que queremos acessar o estilo do elemento por meio de JavaScript. E esse script será bloqueado, desde que os estilos desse elemento sejam atualmente analisados ou carregados
- Também no Chrome, por exemplo, no DCL, os formulários são preenchidos automaticamente.
Figura 3Primeira pintura - o navegador renderizou o primeiro pixel na página.
Primeira pintura com conteúdo - o navegador renderizou o primeiro conteúdo na página.
Primeira pintura significativa - o evento é disparado após o ER determinar que o conteúdo renderizado pode ser útil para o usuário.
Carregue a página inteira e os recursos nela serão carregados, incluindo o iframe.
Sobre FP, FCP, FMP está bem escrito na documentação oficial do
Google para desenvolvedores .
Agora que descobrimos quais eventos ocorreram, podemos ir para a árvore de chamadas (veja a
Figura 1 ) e analisar com mais detalhes quando e por que esses eventos ocorrem.
Analisar HTML - análise de HTML. Você pode escrever um artigo separado sobre isso. Melhor ainda, leia as
especificações.Nós precisamos entender que o navegador baseado em HTML cria o modelo de objeto do documento - o DOM. E, quando estiver pronto e não puder mais afetá-lo, ele dispara o evento DOMContentLoaded.
Camadas compostas são uma combinação de elementos visuais de fontes separadas em imagens únicas para criar a ilusão de que todos esses elementos fazem parte da mesma cena.
Recalcule o estilo. Quaisquer alterações no DOM, adicionando ou removendo elementos, alterando atributos, classes ou usando ferramentas de animação, fazem com que o navegador recalcule os estilos dos elementos e, em muitos casos, o layout da página inteira ou de partes dela. Esse processo é chamado de cálculo de estilo.
Google para desenvolvedoresAnalisar folha de estilos. Se, após a análise, o RE perceber que o HTML está ativado para css, ele inicia o download e a análise antecipada. Após a parsina, o RE cria o Modelo de Objeto CSS, o modelo de objeto CSS.
Em seguida, vem o estágio de anexo, no qual o RE mapeia CSS para OM e DOM, e obtemos uma Render Tree.
Atualizar árvore de camadas (Layout) - layout de uma árvore de camadas ou apenas um layout. Depois de correspondermos ao CSS OM e DOM, podemos descobrir a localização dos elementos e seus tamanhos.
Na maioria das vezes, os elementos que ficam mais baixos no fluxo não podem afetar o posicionamento dos elementos acima; portanto, o layout é executado com mais freqüência sequencialmente - de cima para baixo e da esquerda para a direita. Portanto, o padrão HTML fornece um modelo de fluxo do layout do documento.
Paint - renderizando conteúdo na tela. E somente depois de todas essas etapas, vemos o conteúdo do site na tela: D
Aqui está um breve resumo de todas as etapas no RE:
Figura 4Resumimos:
Os dados no ER vêm do módulo de rede em lotes. Ao receber esses dados, o RE começa a trabalhar com eles, ou seja, a análise de HTML.
Quando o RE vê que um recurso externo é encontrado em HTML, ele fala sobre isso para a Rede e começa a fazer o download e o entrega ao RE novamente.
A reunião da tag <script> de acordo com o padrão RE interrompe a análise e aguarda o download e a execução desse script, e só então continua analisando e construindo a árvore DOM. Isso é resolvido pelos atributos async / defer. Você pode ler mais sobre suas diferenças
aqui.O principal é entender que eles possibilitam continuar analisando o HTML sem esperar pelo processamento do script.
Além disso, os navegadores (no nosso caso, o Chrome) podem bloquear a execução do script se tentar trabalhar (via JavaScript) com o css do elemento cujos estilos estão sendo processados no momento.
Depois que o RE entende que todos os scripts síncronos foram baixados e funcionaram, o HTML é completamente analisado e nada mais nos incomoda, gera o evento DOMContentLoaded e obtemos um objeto #document no navegador com o qual podemos trabalhar.
Em seguida, após concluir a análise do CSS e construir o Modelo de Objeto CSS, o estágio de anexo ocorre, onde a Árvore de Renderização é construída e o Layout (layout dos tamanhos e posições dos blocos). Bem, depois de Layout, há um desenho na tela - Paint. O mecanismo de renderização percorre um longo caminho para que você e eu vejamos isso:
Figura 5Isso é tudo!
Espero que este artigo tenha sido útil para você e agora você entenda como o Rendering Engine funciona.
Tchau :) E até breve. Se você gostou, curta e assine o meu canal :)