Publicado em 31 de março de 2014
Antes que o navegador possa renderizar a página, ele precisa construir as árvores DOM e CSSOM. Por isso, precisamos garantir que o HTML e o CSS sejam enviados ao navegador o mais rápido possível.
Resumo
- Bytes → caracteres → tokens → nós → modelo de objeto.
- A marcação HTML é transformada em um modelo de objeto de documento (DOM); a marcação CSS é transformada em um modelo de objeto CSS (CSSOM).
- DOM e CSSOM são estruturas de dados independentes.
- O painel de desempenho do Chrome DevTools permite capturar e inspecionar os custos de construçã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 um conjunto de regras. - Lexing:os tokens emitidos são convertidos em "objetos", que definem as propriedades e regras deles.
- Construção de DOM: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 é um pai do objeto body, o body é um pai do objeto paragraph, até que toda a representação do documento seja criada.
O resultado final de todo esse processo é o modelo de objeto de documentos (DOM) da nossa página simples, que o navegador usa para todo o processamento futuro da página.
Toda vez 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 DOM. Todo esse processo pode levar algum tempo, principalmente se tivermos uma grande quantidade de HTML para processar.
Se você abrir o Chrome DevTools e gravar uma linha do tempo enquanto a página é carregada, vai poder conferir o tempo real necessário para realizar essa etapa. No exemplo anterior, levamos cerca de 5 ms para converter um trecho de HTML em uma árvore DOM. Para uma página maior, esse processo pode levar muito mais tempo. Ao criar animações suaves, isso pode se tornar um gargalo se o navegador precisar processar grandes quantidades de HTML.
A árvore DOM captura as propriedades e as relações da marcação do documento, mas não informa como o elemento vai ficar quando renderizado. Essa é a responsabilidade do CSSOM.
Modelo de objeto CSS (CSSOM, na sigla em inglês)
Enquanto o navegador estava construindo o DOM da nossa página básica, ele encontrou
um elemento <link>
no <head>
do documento que referenciava uma folha de estilo CSS
externa: style.css
. Prevendo que ele precisa desse recurso para renderizar a
página, ele envia imediatamente uma solicitação para esse recurso, que retorna
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 declarar nossos estilos diretamente na marcação HTML (inline), mas manter o CSS independente do HTML nos permite tratar o conteúdo e o design como questões separadas: designers podem trabalhar com CSS, desenvolvedores podem se concentrar no HTML, além de outras questões.
Assim como no HTML, precisamos converter as regras CSS recebidas em algo que o navegador possa entender e usar. Portanto, repetimos o processo de HTML, mas para CSS em vez de HTML:
Os bytes do CSS são convertidos em caracteres, depois em tokens, depois em nós e, finalmente, são vinculados a uma estrutura em árvore conhecida como "modelo de objetos do CSS" (CSSOM):
Por que o CSSOM tem uma estrutura em árvore? Ao calcular 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 calculados aplicando regras mais específicas, ou seja, as regras "em cascata".
Para deixar isso mais concreto, considere a árvore CSSOM descrita anteriormente. Qualquer texto
contido na tag <span>
que seja colocado no elemento body tem um
tamanho de fonte de 16 pixels e texto vermelho. A diretiva font-size
é transmitida
em cascata do body
para o span
. No entanto, se um span
for filho de uma
tag de parágrafo (p
), o conteúdo dele não será exibido.
Além disso, a árvore descrita anteriormente não é a árvore CSSOM completa e mostra apenas os estilos que decidimos substituir na folha de estilos. Todos os navegadores oferecem um conjunto padrão de estilos, também conhecidos como "estilos de agente do usuário", que é o que aparece quando não fornecemos nossos próprios estilos. Nossos estilos substituem esses padrões.
Para descobrir quanto tempo o processamento do CSS leva, você pode gravar uma linha do tempo nas Ferramentas do desenvolvedor e procurar o evento "Recalculate Style": ao contrário da análise do DOM, a linha do tempo não mostra uma entrada separada de "Parse CSS", mas captura a análise e a construção da árvore CSSOM, além do cálculo recursivo de estilos computados nesse evento.
Nossa folha de estilos triviais leva cerca de 0,6 ms para ser processada e afeta oito elementos na página.Não é muito, mas, mais uma vez, não é sem custo financeiro. No entanto, de onde os oito elementos vêm? O CSSOM e o DOM são estruturas de dados independentes. O navegador está ocultando uma etapa importante. Em seguida, a árvore de renderização será abordada, vinculando o DOM e o CSSOM.