Construção, layout e pintura da árvore de renderização

Publicado em 31 de março de 2014

As árvores do CSSOM e do DOM são combinadas em uma árvore de renderização, que é usada para calcular o layout de cada elemento visível e atua como entrada para o processo de pintura que renderiza os pixels na tela. A otimização de cada uma dessas etapas é essencial para se obter o desempenho de renderização ideal.

Na seção anterior sobre a construção do modelo de objetos, criamos as árvores do DOM e do CSSOM de acordo com as entradas HTML e CSS. No entanto, ambos são objetos independentes que capturam aspectos diferentes do documento: um descreve o conteúdo e o outro, as regras de estilo que precisam ser aplicadas ao documento. Como podemos mesclar os dois para que o navegador renderize pixels na tela?

Resumo

  • As árvores do DOM e do CSSOM se combinam para formar a árvore de renderização.
  • A árvore de renderização contém apenas os nós necessários para renderizar a página.
  • O layout calcula a posição e o tamanho exatos de cada objeto.
  • A última etapa é a pintura, que usa a árvore de renderização final e renderiza os pixels na tela.

Primeiro, o navegador combina o DOM e o CSSOM em uma "árvore de renderização", que captura todo o conteúdo visível do DOM na página e todas as informações de estilo do CSSOM de cada nó.

O DOM e o CSSOM são combinados para criar a árvore de renderização

Para construir a árvore de renderização, o navegador faz, aproximadamente, o seguinte:

  1. Começando na raiz da árvore DOM, através de cada nó visível.

    • Alguns nós não são visíveis (por exemplo, tags script, tags meta e assim por diante) e são omitidos, pois não são refletidos no resultado da renderização.
    • Alguns nós são ocultados usando CSS e também são omitidos da árvore de renderização. Por exemplo, o nó de período, no exemplo acima, está ausente da árvore de renderização porque temos uma regra explícita que define a propriedade "display: none".
  2. Para cada nó visível, encontre as regras do CSSOM correspondentes adequadas e aplique-as.

  3. Emita nós visíveis com conteúdo e estilos processados.

O resultado final é uma árvore de renderização que contém o conteúdo e as informações de estilo de todo o conteúdo visível na tela. Com a árvore de renderização concluída, podemos prosseguir para a fase de "layout".

Até agora, calculamos quais nós devem ficar visíveis e seus estilos computados, mas não calculamos a posição e o tamanho exatos na janela de visualização do dispositivo. Essa é a etapa de "layout", também conhecida como "reflow".

Para determinar o tamanho e a posição exatos de cada objeto, o navegador começa na raiz da árvore de renderização e passa por toda ela. Por exemplo,

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

Faça um teste

O <body> do exemplo anterior contém dois <div>s aninhados: o primeiro <div> (pai) define o tamanho de exibição do nó como 50% da largura da janela de visualização, e o segundo <div>, contido pelo pai, define o width como 50% do pai, ou seja, 25% da largura da janela de visualização.

Como calcular informações de layout

O resultado do processo de layout é um "modelo de caixa", que captura a posição e o tamanho exatos de cada elemento dentro da janela de visualização. Todas as medições relativas são convertidas em pixels absolutos na tela.

Por fim, agora que sabemos quais nós são visíveis, seus estilos computados e sua geometria, podemos passar essas informações para o estágio final, que converte cada nó da árvore de renderização em pixels reais na tela. Essa etapa é frequentemente chamada de "pintura" ou "rasterização".

Esse processo pode demorar um pouco porque o navegador tem bastante trabalho a fazer. No entanto, o Chrome DevTools pode fornecer algumas ideias para as três etapas descritas anteriormente. Examine a fase de layout do nosso exemplo original "hello world":

Medir o layout no DevTools

  • O evento "Layout" captura a construção, a posição e o cálculo de tamanho da árvore de renderização na linha do tempo.
  • Quando o layout é concluído, o navegador emite os eventos "Paint Setup" e "Paint", que convertem a árvore de renderização em pixels na tela.

O tempo necessário para realizar a construção, o layout e a pintura da árvore de renderização varia de acordo com o tamanho do documento, os estilos aplicados e o dispositivo em que ele está sendo executado: quanto maior o documento, mais trabalho o navegador tem; quanto mais complicados os estilos, mais tempo é necessário para a pintura. Por exemplo, uma cor sólida é "barata" para pintar, enquanto uma sombra projetada é "cara" para computar e renderizar.

Finalmente, a página está visível na janela de visualização:

Página Hello World renderizada

Confira um breve resumo das etapas do navegador:

  1. Processe a marcação HTML e crie a árvore do DOM.
  2. Processar a marcação CSS e criar a árvore do CSSOM.
  3. Combinar o DOM e o CSSOM em uma árvore de renderização.
  4. Executar o layout na árvore de renderização para calcular a geometria de cada nó.
  5. Pinta os nós individuais na tela.

A página de demonstração pode parecer básica, mas exige bastante trabalho do navegador. Se o DOM ou o CSSOM forem modificados, você terá que repetir o processo para descobrir que pixels precisam ser renderizados novamente na tela.

Otimizar o caminho crítico de renderização é o processo de minimizar o tempo total gasto nas etapas de 1 a 5 da sequência acima. Isso permite renderizar conteúdo na tela o mais cedo possível, além de reduzir o tempo entre as atualizações da tela após a renderização inicial, ou seja, atingir uma taxa de atualização mais alta para conteúdo interativo.

Feedback