Atraso de apresentação do INP: tamanho do DOM, trabalho de layout e otimização de renderização

Aprenda a encontrar e melhorar problemas de INP causados pelo atraso de apresentação

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-04

Problemas de Interaction to Next Paint (INP) causados pelo atraso de apresentação

Esta página faz parte da nossa série sobre Interaction to Next Paint (INP). O INP mede o tempo total desde uma interação do usuário até a próxima atualização visual. O atraso de apresentação é a terceira e última fase do INP, após o atraso de entrada e o tempo de processamento. Se você é novo no INP, leia primeiro nosso guia sobre como identificar e corrigir problemas de INP.

Resumindo: O Interaction to Next Paint (INP) mede quanto tempo leva para um usuário ver uma mudança visual em uma página após interagir com ela. O INP pode ser dividido em 3 componentes: "atraso de entrada", "tempo de processamento" e "atraso de apresentação".

O atraso de apresentação é o principal fator no INP total, representando cerca de 42% do tempo total do INP em média. Otimizar seu pipeline de renderização e simplificar sua estrutura HTML é a maior alavanca individual para melhorar o INP.

Atraso de Apresentação: Você já clicou em um botão e se perguntou por que demorou uma fração de segundo a mais para ver o resultado? Isso é o Interaction to Next Paint (INP) em ação. O atraso de apresentação é a última etapa do processo de interação, ocorrendo após o clique ser processado, mas antes de você ver qualquer mudança visual.

Entendendo o atraso de apresentação

A apresentação é a fase final de uma interação. O atraso de apresentação representa o tempo que o navegador leva para renderizar as atualizações visuais que seguem a interação. O atraso de apresentação começa quando os manipuladores de eventos da interação terminam de rodar e termina quando o próximo frame (que contém as alterações visuais) é pintado. O atraso de apresentação pode ser afetado por vários fatores, incluindo a complexidade do layout, o tamanho do DOM e a quantidade de trabalho de renderização necessária.

inp 3 stage processing time highlighted

O Interaction to Next Paint (INP) pode ser dividido em 3 subpartes: "Atraso de Entrada", "Tempo de Processamento" e "Atraso de Apresentação".

O atraso de apresentação e o INP

O atraso de apresentação é a última fase do INP. Em média, o atraso de apresentação representa cerca de 42% do tempo total do INP, tornando-o o maior colaborador individual para interações lentas.

inp distribution input delay highlighted

No CoreDash, coletamos milhões de pontos de dados de Core Web Vitals a cada hora. Com base nesses dados, o atraso de apresentação responde por 42% do Interaction to Next Paint. Isso é mais do que o tempo de processamento (40%) e significativamente mais do que o atraso de entrada (18%). Apesar de ser o maior colaborador, o atraso de apresentação costuma ser a fase mais difícil de otimizar, pois envolve o pipeline de renderização do navegador e não o código da sua aplicação.

Exemplo de atraso de apresentação: Imagine que você está no celular navegando em um site de e-commerce de sapatos. Você toca na imagem de um produto para ver mais detalhes. No entanto, seu celular é um pouco antigo e tem dificuldades para acompanhar. Você toca na imagem (Interação). O celular leva algum tempo para processar a requisição e atualizar a tela (Tempo de Processamento). O site precisa renderizar a nova página com a imagem ampliada e os detalhes. Por fim, leva um tempo perceptível para que os novos detalhes do produto e a imagem apareçam na tela (Atraso de Apresentação). Esse atraso no INP pode ser frustrante para os usuários e é por isso que é importante corrigi-lo.

O que causa um alto atraso de apresentação?

O atraso de apresentação engloba todo o trabalho que o navegador faz após a conclusão dos manipuladores de eventos e antes dos pixels aparecerem na tela. Isso inclui recálculo de estilo, cálculo de layout, pintura e composição. Vários fatores contribuem para um alto atraso de apresentação:

Tamanho grande do DOM

Um DOM grande ou profundamente aninhado é uma das causas mais comuns de um alto atraso de apresentação. Toda vez que o navegador precisa atualizar o estado visual da página após uma interação, ele deve recalcular estilos, calcular o layout e repintar os elementos afetados. O custo de cada uma dessas etapas escala com o número de nós do DOM afetados.

O Google recomenda manter seu DOM abaixo de 1.400 elementos, com uma profundidade máxima de 32 níveis e não mais que 60 elementos filhos por nó pai (consulte a auditoria de tamanho do DOM do Lighthouse). Quando seu DOM excede esses limites, o navegador gasta muito mais tempo no recálculo de estilo e no cálculo de layout após cada interação.

Considere este cenário: um usuário clica em um botão que alterna uma classe CSS em um elemento container. Se esse container tiver 5.000 nós descendentes, o navegador precisará recalcular os estilos de potencialmente todos eles, mesmo que apenas alguns elementos mudem visualmente. Esse recálculo de estilo ocorre de forma síncrona antes da próxima pintura, aumentando diretamente o atraso de apresentação.

Para técnicas específicas de redução do DOM, leia nosso guia sobre como corrigir o tamanho excessivo do DOM.

Trabalho excessivo de layout

O layout (também chamado de "reflow") é o processo no qual o navegador calcula a posição e as dimensões de cada elemento visível na página. Após uma interação que modifica o DOM ou altera propriedades CSS que afetam a geometria (width, height, margin, padding, top, left), o navegador precisa realizar o layout antes de poder pintar o frame atualizado.

Dois padrões são particularmente prejudiciais para o atraso de apresentação:

Layout síncrono forçado ocorre quando o JavaScript lê uma propriedade de layout (como offsetHeight ou getBoundingClientRect()) após fazer uma alteração no DOM que invalida o layout. O navegador é forçado a executar o layout de forma síncrona, dentro do seu manipulador de eventos, para retornar um valor preciso. Esse trabalho de layout se torna parte do tempo de processamento, mas qualquer layout subsequente acionado por novas alterações no DOM torna-se parte do atraso de apresentação.

Layout thrashing é o padrão repetitivo de gravar no DOM e ler propriedades de layout em um loop. Cada leitura força o navegador a recalcular o layout, e cada gravação invalida o layout novamente. Isso pode causar dezenas ou até centenas de cálculos de layout desnecessários por interação. Veja um exemplo de layout thrashing e como corrigi-lo:

// RUIM: Layout thrashing dentro de um loop
function resizeItems() {
  const items = document.querySelectorAll('.item');
  items.forEach(item => {
    // Leitura (força o layout)
    const parentWidth = item.parentElement.offsetWidth;
    // Gravação (invalida o layout)
    item.style.width = parentWidth + 'px';
  });
}

// BOM: Agrupar leituras e depois agrupar gravações
function resizeItems() {
  const items = document.querySelectorAll('.item');
  // Lê todos os valores primeiro
  const widths = Array.from(items).map(
    item => item.parentElement.offsetWidth
  );
  // Depois grava todos os valores
  items.forEach((item, i) => {
    item.style.width = widths[i] + 'px';
  });
}

Renderização no lado do cliente em Single Page Applications

A renderização de HTML no lado do cliente pode impactar significativamente o atraso de apresentação, principalmente em Single Page Applications (SPAs). Quando uma interação do usuário aciona uma mudança de rota ou uma grande atualização de interface, o framework SPA precisa:

  1. Executar o algoritmo de diff do DOM virtual para determinar o que mudou
  2. Aplicar as mutações resultantes ao DOM real
  3. Acionar o recálculo de estilo e o layout para todos os elementos afetados
  4. Pintar o frame atualizado

Em aplicações React, o processo de reconciliação do DOM virtual faz parte do tempo de processamento, mas as mutações resultantes no DOM e seu custo de renderização entram no atraso de apresentação. Quanto mais nós do DOM sua árvore de componentes produzir, mais cara será a reconciliação e o trabalho de renderização subsequente.

Para mitigar isso em aplicações React e Next.js:

  • Use React.memo() para evitar re-renderizações desnecessárias de componentes filhos que recebem as mesmas props.
  • Use useDeferredValue() para valores que acionam re-renderizações caras, permitindo que o React priorize atualizações mais urgentes.
  • Mantenha as árvores de componentes rasas. Hierarquias de componentes profundamente aninhadas produzem um DOM profundamente aninhado, o que aumenta o custo da reconciliação e da renderização no navegador.
  • Use bibliotecas de virtualização (como react-window ou @tanstack/react-virtual) para listas longas, de modo que o DOM contenha apenas os itens visíveis.

Reduzindo o atraso de apresentação

Minimizar o tamanho do DOM

O maior ganho para o atraso de apresentação é manter o DOM pequeno:

  • Remova elementos HTML não utilizados, especialmente divs de envoltório profundamente aninhadas.
  • Use virtualização de lista para listas longas (renderize apenas os itens visíveis mais um pequeno buffer).
  • Achate estruturas profundamente aninhadas onde for possível.
  • Use CSS Grid e Flexbox em vez de divs aninhadas para o layout.
// Virtualizar listas longas para reduzir o tamanho do DOM
// Antes: 10.000 itens no DOM

<ul>
  {allItems.map(item => 
     <li key="{item.id}">{item.name}</li>)
   }
</ul>

// Depois: apenas itens visíveis no DOM (usando react-window)
import { FixedSizeList } from 'react-window';
<fixedsizelist height="{600}" 
               itemcount="{allItems.length}" 
               itemsize="{50}" width="100%">  
  {({ index, style }) => (
    <div style="{style}">{allItems[index].name}</div>
  )}
</fixedsizelist>

Use content-visibility para renderizar sob demanda o conteúdo fora da tela

A propriedade CSS content-visibility instrui o navegador a pular a renderização do conteúdo fora da tela até que o usuário role para perto dele. Isso reduz a quantidade de trabalho de renderização durante as interações ao limitar o escopo do recálculo de estilo e do layout à parte visível da página.

/* Aplica content-visibility a seções abaixo da dobra (below the fold) */
.below-fold-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

/* Aplica a itens individuais em listas longas */
.list-item {
  content-visibility: auto;
  contain-intrinsic-size: auto 80px;
}

A propriedade contain-intrinsic-size fornece uma altura estimada para que o navegador calcule o tamanho da barra de rolagem corretamente sem renderizar o conteúdo. Isso evita mudanças de layout quando o usuário rola a página e o conteúdo se torna visível.

Para mais estratégias de otimização de CSS que reduzem o custo de renderização, consulte nosso guia sobre como remover CSS não utilizado.

Minimizar o trabalho de layout acionado por interações

Ao planejar interações, prefira propriedades CSS que não acionem o layout. Propriedades como transform e opacity podem ser tratadas pelo compositor da GPU sem acionar o layout ou a pintura. Em vez de animar top, left, width ou height, use transform: translate() e transform: scale(). Para a lista completa de propriedades CSS que acionam o layout, consulte o guia de desempenho de renderização do web.dev.

Use a propriedade CSS will-change para indicar ao navegador que um elemento será animado. Isso permite que o navegador crie uma camada de composição separada para o elemento, isolando sua renderização do restante da página:

/* Promove elementos para sua própria camada de composição */
.animated-element {
  will-change: transform, opacity;
}

/* Alterna a visibilidade com opacity em vez de display */
.modal {
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
  transition: opacity 0.2s, transform 0.2s;
}

.modal.active {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

Identificando atrasos de apresentação longos

Para identificar atrasos de apresentação longos, você pode usar o profiler de desempenho do Chrome. Abra o DevTools (Ctrl+Shift+I), navegue até a aba Performance, clique em gravar e interaja com a página.

Você pode então analisar a linha do tempo de uma interação e visualizar as diferentes fases, incluindo o atraso de apresentação. Ao examinar as atualizações de renderização que ocorrem após o término dos manipuladores de eventos, você consegue identificar gargalos que contribuem para um atraso de apresentação longo. Procure por entradas grandes de "Recalculate Style", "Layout" e "Paint" na linha do tempo. Elas representam o trabalho que o navegador realiza durante a fase de atraso de apresentação.

inp presentation delay devtools

Identificando o atraso de apresentação com dados RUM

O Real User Monitoring (RUM) fornece atualizações em tempo real sobre métricas importantes relacionadas aos Core Web Vitals, como o Interaction to Next Paint e suas subpartes, incluindo o atraso de apresentação. Uma ferramenta RUM como o CoreDash divide cada interação do INP em suas três fases, permitindo que você veja se o atraso de apresentação é o gargalo para suas páginas e segmentos de usuários específicos.

Medindo o atraso de apresentação com Long Animation Frames (LoAF)

A API Long Animation Frames (LoAF) mostra exatamente o que causa atrasos de renderização durante as interações do usuário. A API fornece dados de tempo para separar o tempo de processamento do atraso de apresentação e identificar quais scripts atrasam a renderização.

As principais propriedades da LoAF para entender o atraso de apresentação são:

  • renderStart: quando o navegador iniciou a fase de renderização (recálculo de estilo, layout, pintura)
  • styleAndLayoutStart: quando começou o cálculo de estilo e layout
  • duration: duração total do frame de animação longo (long animation frame)
  • blockingDuration: quanto do frame foi bloqueado por scripts

A LoAF é atualmente exclusiva do Chromium (Chrome 123+). Para outros navegadores, use rastreamentos (traces) do painel Performance do Chrome DevTools para analisar o trabalho de renderização.

A diferença entre o fim da execução do script e o fim do frame representa o custo de renderização puro, que é o atraso de apresentação. Veja como observar e registrar esses dados:

// Mede o atraso de apresentação usando a API LoAF
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > 50) {
      const scriptEnd = Math.max(
        ...entry.scripts.map(s => s.startTime + s.duration)
      );
      const presentationDelay = (
        entry.startTime + entry.duration
      ) - Math.max(scriptEnd, entry.renderStart);

      console.log('Detalhamento do atraso de apresentação:', {
        totalDuration: entry.duration,
        renderStart: entry.renderStart,
        styleAndLayoutStart: entry.styleAndLayoutStart,
        estimatedPresentationDelay: presentationDelay,
        scriptCount: entry.scripts.length
      });
    }
  }
});

observer.observe({
  type: 'long-animation-frame',
  buffered: true
});

Ferramentas RUM como o CoreDash integram os dados da LoAF e mostram quais scripts e alterações no DOM causam atrasos de renderização, com atribuição completa de scripts.

Explore as outras fases do INP

Para manter seu INP sob controle, aborde também as outras duas fases:

  • Atraso de Entrada: Minimize o tempo de espera antes que os manipuladores de eventos comecem a ser executados. O atraso de entrada é normalmente a menor fase, mas apresenta picos durante a inicialização da página, quando a main thread está ocupada.
  • Tempo de Processamento: Otimize o código do manipulador de eventos que roda durante a interação. Na maioria das páginas, é aqui que a maior parte do seu esforço de otimização trará resultados.

Para um fluxo de trabalho completo de diagnóstico, consulte nosso guia sobre como encontrar e corrigir problemas de INP. Para estratégias adicionais de otimização de renderização, explore nossos guias sobre como corrigir o tamanho excessivo do DOM e como remover CSS não utilizado. Retorne para a página central do INP para ver a visão geral completa.

O score do Lighthouse não conta a história toda.

Os teus visitantes estão em Android sobre 4G. Eu analiso o que eles apanham na prática.

Analisar dados reais
Atraso de apresentação do INP: tamanho do DOM, trabalho de layout e otimização de renderizaçãoCore Web Vitals Atraso de apresentação do INP: tamanho do DOM, trabalho de layout e otimização de renderização