Noções básicas sobre o caminho crítico

O caminho crítico de renderização se refere às etapas envolvidas até que a página da Web inicie a renderização no navegador. Para renderizar páginas, os navegadores precisam do próprio documento HTML, bem como de todos os recursos essenciais necessários para renderizar esse documento.

O processo de conseguir o documento HTML para o navegador foi abordado no módulo anterior de considerações gerais de desempenho de HTML. No entanto, neste módulo, analisaremos mais o que o navegador faz depois de fazer o download do documento HTML para renderizar a página.

Renderização progressiva

A web é distribuída por natureza. Ao contrário dos aplicativos nativos que são instalados antes do uso, os navegadores não podem depender de sites com todos os recursos necessários para renderizar a página. Portanto, os navegadores são muito bons em renderizar as páginas progressivamente. Normalmente, os apps nativos têm uma fase de instalação e depois uma de execução. No entanto, para páginas e apps da Web, as linhas entre essas duas fases são muito menos distintas, e os navegadores foram projetados especificamente com isso em mente.

Depois que o navegador tem recursos para renderizar uma página, ele normalmente começa a fazer isso. Portanto, a escolha é sobre quando renderizar: quando é cedo demais?

Se o navegador for renderizado assim que possível com HTML, mas antes de ter CSS ou JavaScript necessário, a página parecerá corrompida e mudará consideravelmente para a renderização final. Essa é uma experiência pior do que apresentar inicialmente uma tela em branco por um tempo, até que o navegador tenha mais desses recursos necessários para uma renderização inicial que ofereça uma melhor experiência do usuário.

Por outro lado, se o navegador aguardar a disponibilidade de todos os recursos, em vez de fazer qualquer renderização sequencial, o usuário vai ficar esperando por muito tempo. Isso geralmente é desnecessário se a página tiver sido usada em um momento muito anterior.

O navegador precisa saber o número mínimo de recursos que precisa aguardar para evitar uma experiência obviamente corrompida. Por outro lado, o navegador também não deve esperar mais do que o necessário para apresentar ao usuário algum conteúdo. A sequência de etapas que o navegador executa antes de executar a renderização inicial é conhecida como caminho crítico de renderização.

Entender o caminho crítico de renderização pode ajudar a melhorar o desempenho da Web, garantindo que você não bloqueie a renderização inicial da página mais do que o necessário. Ao mesmo tempo, é importante também não permitir que a renderização aconteça muito cedo, removendo os recursos necessários para essa renderização inicial do caminho crítico de renderização.

O caminho de renderização (crítico)

O caminho de renderização envolve as seguintes etapas:

  • Construir o Document Object Model (DOM) a partir do HTML.
  • Como criar o modelo de objeto CSS (CSSOM) a partir do CSS.
  • Aplicar qualquer JavaScript que altere o DOM ou o CSSOM.
  • Como criar a árvore de renderização do DOM e do CSSOM.
  • Execute operações de estilo e layout na página para ver quais elementos se encaixam no lugar.
  • Pinte os pixels dos elementos na memória.
  • Componha os pixels se algum deles se sobrepuser.
  • Desenhe fisicamente todos os pixels resultantes na tela.
Um diagrama do processo de renderização, conforme detalhado na lista anterior.

O usuário verá o conteúdo na tela somente após a conclusão de todas essas etapas.

Esse processo de renderização ocorre várias vezes. A renderização inicial invoca esse processo, mas à medida que mais recursos que afetam a renderização da página são disponibilizados, o navegador executa esse processo novamente, ou talvez apenas partes dele, para atualizar o que é mostrado ao usuário. O caminho crítico de renderização se concentra no processo descrito anteriormente para a renderização inicial e depende dos recursos críticos necessários para ele.

Quais recursos estão no caminho crítico de renderização?

O navegador precisa aguardar o download de alguns recursos críticos antes de concluir a renderização inicial. Esses recursos incluem:

  • Parte do HTML.
  • CSS de bloqueio de renderização no elemento <head>
  • JavaScript de bloqueio de renderização no elemento <head>

Um ponto importante é que o navegador processa HTML de modo contínuo. Assim que o navegador recebe qualquer parte do HTML de uma página, ele começa a processá-la. Então, o navegador pode decidir renderizá-lo bem antes de receber o restante do HTML de uma página.

É importante ressaltar que, na renderização inicial, o navegador não normalmente esperará:

  • Todo o HTML.
  • Fontes.
  • imagens
  • JavaScript sem bloqueio de renderização fora do elemento <head> (por exemplo, elementos <script> colocados no final do HTML).
  • CSS sem bloqueio de renderização fora do elemento <head> ou CSS com um valor de atributo media que não se aplica à janela de visualização atual.

Fontes e imagens geralmente são consideradas pelo navegador como conteúdo a ser preenchido durante novas renderizações de páginas subsequentes. Portanto, elas não precisam manter a renderização inicial. No entanto, isso pode significar que áreas de espaço em branco são deixadas na renderização inicial enquanto o texto fica oculto enquanto aguarda as fontes ou até que as imagens estejam disponíveis. Pior ainda é quando não há espaço suficiente para determinados tipos de conteúdo, principalmente quando as dimensões da imagem não são fornecidas no HTML, o layout da página pode mudar quando esse conteúdo for carregado mais tarde. Esse aspecto da experiência do usuário é medido pela métrica Mudança de layout cumulativa (CLS, na sigla em inglês).

O elemento <head> é fundamental para processar o caminho crítico de renderização. Tanto que a próxima seção aborda isso em mais detalhes. A otimização do conteúdo do elemento <head> é um aspecto fundamental do desempenho da Web. Para entender o caminho crítico de renderização por enquanto, você só precisa saber que o elemento <head> contém metadados sobre a página e os recursos dela, mas nenhum conteúdo real que o usuário possa acessar. O conteúdo visível fica no elemento <body> que segue o elemento <head>. Antes que o navegador possa renderizar qualquer conteúdo, ele precisa tanto do conteúdo quanto dos metadados sobre como renderizar.

No entanto, nem todos os recursos referenciados no elemento <head> são estritamente necessários para a renderização inicial da página. Portanto, o navegador aguarda apenas os que são. Para identificar quais recursos estão no caminho crítico de renderização, é preciso entender CSS e JavaScript com bloqueio de renderização e analisador.

Recursos que bloqueiam a renderização

Alguns recursos são considerados tão essenciais que o navegador pausa a renderização da página até resolvê-los. O CSS se enquadra nessa categoria por padrão.

Quando um navegador encontra CSS, seja um CSS in-line em um elemento <style> ou um recurso referenciado externamente especificado por um elemento <link rel=stylesheet href="...">, ele evita renderizar mais conteúdo até concluir o download e o processamento desse CSS.

Só porque um recurso bloqueia a renderização não significa necessariamente que ele impede que o navegador faça qualquer outra coisa. Os navegadores tentam ser o mais eficientes possível. Portanto, quando um navegador percebe que precisa fazer o download de um recurso CSS, ele faz uma solicitação e pausa a renderização, mas continua processando o restante do HTML e procura outros trabalhos nesse meio tempo.

Recursos de bloqueio de renderização, como CSS, usados para bloquear toda a renderização da página quando eles são descobertos. Isso significa que alguns CSSs bloqueiam a renderização ou não dependem da descoberta pelo navegador. Alguns navegadores (inicialmente o Firefox e agora também o Chrome) bloqueiam apenas a renderização de conteúdo abaixo do recurso de bloqueio de renderização. Isso significa que, para o caminho crítico de bloqueio de renderização, normalmente estamos interessados em recursos bloqueadores de renderização no <head>, porque eles efetivamente bloqueiam a renderização de toda a página.

Uma inovação mais recente é o atributo blocking=render, adicionado ao Chrome 105. Isso permite que os desenvolvedores marquem explicitamente um elemento <link>, <script> ou <style> como bloqueador de renderização até que o elemento seja processado, mas ainda permite que o analisador continue processando o documento nesse meio tempo.

Recursos que bloqueiam o analisador

Os recursos de bloqueio de analisador são aqueles que impedem o navegador de procurar outro trabalho a fazer ao continuar analisando o HTML. Por padrão, o JavaScript bloqueia o analisador (a menos que especificamente marcado como assíncrono ou adiado), já que o JavaScript pode mudar o DOM ou o CSSOM após a execução. Portanto, o navegador não pode continuar processando outros recursos até descobrir o impacto total do JavaScript solicitado no HTML de uma página. O JavaScript síncrono bloqueia o analisador.

Os recursos que bloqueiam o analisador também bloqueiam a renderização. Como o analisador não pode continuar além de um recurso de bloqueio de análise até que seja totalmente processado, ele não pode acessar e renderizar o conteúdo depois dele. O navegador pode renderizar qualquer HTML recebido até o momento enquanto aguarda. No entanto, em relação ao caminho crítico de renderização, os recursos de bloqueio de analisador no <head> significam que todo o conteúdo da página está bloqueado para ser renderizado.

O bloqueio do analisador pode ter um alto custo de desempenho, muito mais do que apenas o bloqueio de renderização. Por esse motivo, os navegadores tentarão reduzir esse custo usando um analisador de HTML secundário, conhecido como verificador de pré-carregamento, para fazer o download de recursos futuros enquanto o analisador de HTML principal estiver bloqueado. Embora não seja tão bom quanto analisar o HTML, ele pelo menos permite que as funções de rede no navegador funcionem antes do analisador bloqueado, o que significa que será menos provável que ele seja bloqueado novamente no futuro.

Identificar recursos de bloqueio

Muitas ferramentas de auditoria de desempenho identificam recursos que bloqueiam a renderização e o analisador. WebPageTest marca os recursos de bloqueio de renderização com um círculo laranja à esquerda do URL do recurso:

Uma captura de tela de um diagrama de hierarquia de rede gerado pelo WebPageTest. Os recursos de bloqueio do analisador são indicados por um círculo laranja à esquerda do URL do recurso, e o tempo de início de renderização é identificado por uma linha sólida verde-escura.

É preciso fazer o download e processar todos os recursos de bloqueio de renderização antes que ela possa ser iniciada, o que é notado pela linha verde sólida na hierarquia.

O Lighthouse também destaca os recursos de bloqueio de renderização, mas de maneira mais sutil, e somente se o recurso realmente atrasar a renderização da página. Isso pode ser útil para evitar falsos positivos quando você está minimizando o bloqueio de renderização. Executar o mesmo URL da página que a figura anterior do WebPageTest pelo Lighthouse identifica apenas uma das folhas de estilo como um recurso bloqueador de renderização.

Captura de tela da auditoria do Lighthouse para eliminar recursos bloqueadores de renderização. A auditoria mostra os recursos que bloqueiam a renderização e o tempo de bloqueio.

Otimizar o caminho crítico de renderização

Otimizar o caminho crítico de renderização envolve reduzir o tempo para receber o HTML (representado pela métrica Tempo até o primeiro byte (TTFB, na sigla em inglês))), conforme detalhado no módulo anterior, e reduzir o impacto dos recursos de bloqueio de renderização. Esses conceitos serão investigados nos próximos módulos.

O caminho crítico de renderização de conteúdo

Por muito tempo, o caminho crítico de renderização se preocupa com a renderização inicial. No entanto, surgiram mais métricas centradas no usuário do desempenho da Web, que questionam se o ponto final do caminho crítico de renderização precisa ser a primeira exibição ou uma das exibições de maior conteúdo que aparecem depois.

Outra opção é se concentrar no tempo até a Maior exibição de conteúdo (LCP), ou até mesmo na Primeira exibição de conteúdo (FCP, na sigla em inglês), como parte de um caminho de renderização de conteúdo (ou o caminho da chave, como outros podem chamá-lo). Nesse caso, talvez seja necessário incluir recursos que não estejam necessariamente bloqueando, como é a definição típica do caminho crítico de renderização, mas que são necessários para renderizar exibições de conteúdo.

Independentemente da sua definição exata do que você define como "crítico", entender o que armazena qualquer renderização inicial e seu conteúdo principal é importante. A primeira exibição mede a primeira oportunidade possível de renderizar qualquer coisa para o usuário. O ideal é que você tenha algo significativo, não algo como uma cor de fundo, por exemplo. Porém, mesmo que não seja conteúdo, ainda há valor em apresentar algo ao usuário, que é um argumento para medir o caminho crítico de renderização conforme definido tradicionalmente. Ao mesmo tempo, também há valor em medir quando o conteúdo principal é apresentado ao usuário.

Identificar o caminho de renderização de conteúdo

Muitas ferramentas podem identificar elementos da LCP e quando eles são renderizados. Além do elemento LCP, o Lighthouse também ajuda a identificar as fases da LCP e o tempo gasto em cada uma delas para ajudar você a entender onde concentrar melhor seus esforços de otimização:

Uma captura de tela da auditoria de LCP do Lighthouse, que mostra o elemento da LCP de uma página e o tempo gasto em fases como TTFB, atraso de carregamento, tempo de carregamento e atraso de renderização.

Para locais mais complexos, o Lighthouse também destaca cadeias de solicitações importantes em uma auditoria separada:

Uma captura de tela do diagrama de cadeia de solicitações crítica do Lighthouse, que mostra quais recursos críticos estão aninhados abaixo de outros recursos críticos, bem como a latência total envolvida na cadeia de solicitações crítica.

Essa auditoria do Lighthouse observa todos os recursos carregados com alta prioridade. Por isso, ela inclui fontes da Web e outros conteúdos que o Chrome define como recursos de alta prioridade, mesmo que não estejam bloqueando a renderização.

teste seus conhecimentos

A que se refere o caminho crítico de renderização?

A quantidade mínima de recursos necessários para executar a renderização inicial da página.
A quantidade mínima de recursos necessários para renderizar completamente uma página.

Quais recursos estão envolvidos no caminho crítico de renderização?

CSS de bloqueio de renderização no elemento <head>
Parte do HTML.
JavaScript de bloqueio de renderização no elemento <head>

Por que o bloqueio de renderização é uma parte necessária da renderização da página?

Evitar que uma página seja renderizada inicialmente em um estado inutilizável ou aparentemente corrompido.
Impedir que os usuários vejam uma página até que ela seja totalmente renderizada.

Por que o JavaScript bloqueia o analisador de HTML (supondo que os atributos defer, async ou module não estejam especificados em um elemento <script>)?

O JavaScript síncrono deve ser executado quando o analisador o alcança, pois pode alterar o DOM.
Todo JavaScript bloqueia os analisadores, independentemente desses atributos.
Sem pelo menos um desses atributos, um <script> bloqueia o analisador e a renderização.

A seguir: otimizar o carregamento de recursos

Este módulo abordou um pouco da teoria por trás de como o navegador renderiza uma página da Web e, em especial, o que é necessário para concluir a renderização inicial de uma página. O próximo módulo analisa como esse caminho de renderização pode ser otimizado aprendendo como otimizar o carregamento de recursos.