Publicado em 31 de março de 2014
Antes de renderizar a página, o navegador precisa construir as árvores do DOM e do CSSOM. Como resultado, precisamos garantir a entrega mais rápida possível do HTML e do CSS ao navegador.
Resumo
- Bytes → caracteres → tokens → nós → modelo de objetos.
- A marcação HTML é transformada em um Document Object Model (DOM), e a marcação CSS é transformada em um CSS Object Model (CSSOM).
- DOM e CSSOM são estruturas de dados independentes.
- O painel Performance do Chrome DevTools permite capturar e inspecionar os custos de criação e processamento do DOM e do CSSOM.
Modelo de objeto de documentos (DOM)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<title>Critical Path</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
Comece com o caso mais simples possível: uma página HTML simples com texto e uma única imagem. Como o navegador processa essa página?
- Conversão:o navegador lê os bytes brutos de HTML do disco ou da rede e os converte em caracteres individuais com base na codificação especificada do arquivo (por exemplo, UTF-8).
- Tokenização: o navegador converte strings de caracteres em tokens
distintos, conforme especificado pelo padrão HTML5 do W3C,
por exemplo,
<html>
,<body>
e outras strings entre colchetes. Cada token tem um significado especial e o próprio conjunto de regras. - Lexing:os tokens emitidos são convertidos em "objetos", que definem as propriedades e regras deles.
- Construção do DOM: por fim, como a marcação HTML define relações entre tags diferentes (algumas tags estão contidas em outras), os objetos criados são vinculados em uma estrutura de dados em árvore que também captura as relações pai-filho definidas na marcação original: o objeto HTML é pai do objeto body, o body é pai do objeto paragraph, até que toda a representação do documento seja criada.
O resultado final de todo esse processo é o Document Object Model (DOM) da nossa página simples, que é usado pelo navegador para todos os demais processamentos da página.
Sempre que o navegador processa a marcação HTML, ele passa por todas as etapas definidas anteriormente: converter bytes em caracteres, identificar tokens, converter tokens em nós e criar a árvore do DOM. Esse processo todo pode demorar um pouco, principalmente se houver uma grande quantidade de HTML a processar.
Se você abrir o Chrome DevTools e gravar uma linha do tempo durante o carregamento da página, vai conferir o tempo real necessário para executar essa etapa. No exemplo anterior, foram necessários cerca de 5 ms para converter um bloco de HTML em uma árvore do DOM. Em uma página maior, esse processo poderia demorar muito mais. Ao criar animações suaves, isso pode se tornar um gargalo se o navegador tiver que processar grandes quantidades de HTML.
A árvore do DOM captura as propriedades e os relacionamentos da marcação do documento, mas não informa qual será a aparência do elemento quando renderizado. Essa é a responsabilidade do CSSOM.
Modelo de objeto CSS (CSSOM)
Enquanto o navegador estava construindo o DOM da nossa página básica, encontrou
um elemento <link>
no <head>
do documento que referenciava uma folha de estilo
CSS externa: style.css
. Prevendo que esse recurso será necessário para renderizar a
página, o navegador envia imediatamente uma solicitação para esse recurso, que é devolvida
com o seguinte conteúdo:
body {
font-size: 16px;
}
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
Poderíamos ter declarado os estilos diretamente na marcação HTML (inline), mas a manutenção do CSS independente do HTML nos permite tratar conteúdo e design como assuntos separados. Os designers podem trabalhar no CSS, os desenvolvedores podem se concentrar no HTML e assim por diante.
Assim como no HTML, precisamos converter as regras CSS recebidas em algo que o navegador possa entender e usar. Portanto, repetimos o processo do HTML, mas para CSS em vez de HTML:
Os bytes do CSS são convertidos em caracteres, depois em tokens, nós e, por fim, são vinculados em uma estrutura de árvore conhecida como "CSS Object Model" (CSSOM):
Por que o CSSOM tem uma estrutura de árvore? Ao computar o conjunto final de estilos para qualquer objeto na página, o navegador começa com a regra mais geral aplicável a esse nó (por exemplo, se ele for filho de um elemento do corpo, todos os estilos do corpo serão aplicados) e, em seguida, refina recursivamente os estilos computados aplicando regras mais específicas, ou seja, as regras "em cascata".
Para sermos mais claros, vamos considerar a árvore do CSSOM descrita anteriormente. Todo o texto
contido na tag <span>
colocado dentro do elemento body tem um
tamanho de fonte de 16 pixels e texto vermelho. A diretiva font-size
é aplicada em cascata
do body
ao span
. No entanto, se um span
for filho de uma
tag de parágrafo (p
), o conteúdo dela não será exibido.
Além disso, observe que a árvore descrita anteriormente não é a árvore do CSSOM completa e mostra apenas os estilos que decidimos substituir na nossa folha de estilo. Todo navegador oferece um conjunto padrão de estilos, também conhecido como "estilos de user-agent", que é o que vemos quando não fornecemos o nosso próprio conjunto de estilos. Nossos estilos substituem esses padrões.
Para saber quanto tempo leva o processamento de CSS, grave uma linha do tempo no DevTools e procure o evento "Recalculator Style". Ao contrário da análise do DOM, a linha do tempo não mostra uma entrada "Parse CSS" separada. Em vez disso, ela captura a análise e a construção da árvore de CSSOM, além do cálculo recursivo de estilos calculados nesse evento.
Nossa folha de estilo simples leva cerca de 0,6 ms para ser processada e afeta oito elementos da página. Não é muito, mas, mais uma vez, nada que possa ser ignorado. No entanto, de onde vieram os oito elementos? O CSSOM e o DOM são estruturas de dados independentes. O que acontece é que o navegador está escondendo uma etapa importante. Em seguida, vamos falar sobre a árvore de renderização, que vincula o DOM e o CSSOM.