INP Presentation Delay: Tamanho do DOM, trabalho de layout e otimização de renderização
Aprenda como encontrar e melhorar problemas de INP causados pelo presentation delay

Problemas de Interaction to Next Paint (INP) causados pelo presentation delay
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 presentation delay é a terceira e última fase do INP, seguindo o input delay e o processing time. Se você é novo no INP, leia primeiro o nosso guia sobre como identificar e corrigir problemas de INP.
Em resumo: 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. Este INP pode ser dividido em 3 componentes: "input delay", "processing time", e "presentation delay".
O presentation delay é o principal contribuinte para o INP total, representando cerca de 42% do tempo total de INP, em média. Otimizar sua pipeline de renderização e simplificar sua estrutura HTML é a maior alavanca individual para melhorar o INP.
Presentation Delay: 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 presentation delay é a última etapa do processo de interação, entrando em ação após o seu clique ter sido processado, mas antes de você ver qualquer mudança visual.
Table of Contents!
- Problemas de Interaction to Next Paint (INP) causados pelo presentation delay
- Entendendo o presentation delay
- Presentation delay e o INP
- O que causa um alto presentation delay?
- Reduzindo o presentation delay
- Identificando longos presentation delays
- Identificando o presentation delay com dados de RUM
- Medindo o presentation delay com Long Animation Frames (LoAF)
- Explore as outras fases do INP
Entendendo o presentation delay
A apresentação (presentation) é a fase final de uma interação. O presentation delay representa o tempo que o navegador leva para renderizar as atualizações visuais que seguem a interação. O presentation delay começa quando os manipuladores de eventos (event handlers) da interação terminam de rodar e termina quando o próximo quadro (contendo as mudanças visuais) é pintado (painted). O presentation delay 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.

O Interaction to Next Paint (INP) pode ser dividido em 3 subpartes: "Input Delay", "Processing Time", e "Presentation Delay".
Presentation delay e o INP
O presentation delay é a última fase do INP. Em média, o presentation delay compõe cerca de 42% do tempo total de INP, tornando-o o maior contribuinte individual para interações lentas.

No CoreDash coletamos milhões de pontos de dados de Core Web Vitals a cada hora. Com base nesses dados, o presentation delay representa 42% do Interaction to Next Paint. Isso é mais do que o processing time (40%) e significativamente mais do que o input delay (18%). Apesar de ser o maior contribuinte, o presentation delay costuma ser a fase mais difícil de otimizar porque envolve a pipeline de renderização do navegador, em vez do código da sua aplicação.
Exemplo de presentation delay: Imagine que você está no seu celular navegando em um site de e-commerce procurando um novo par de sapatos. Você toca na imagem de um produto para ver mais detalhes. No entanto, seu celular é um pouco antigo e luta para acompanhar.
Você toca na imagem (Interação). O celular leva algum tempo para processar a solicitação e atualizar a tela (Processing Time). O site precisa renderizar a nova página com a imagem maior e os detalhes. Finalmente, leva um tempo perceptível para os novos detalhes do produto e a imagem aparecerem na sua tela (Presentation Delay). Esse atraso no INP pode ser frustrante para os usuários e é por isso que é importante corrigi-lo.
O que causa um alto presentation delay?
O presentation delay engloba todo o trabalho que o navegador faz depois que seus event handlers terminam e antes que os pixels apareçam na tela. Isso inclui recálculo de estilo, computação de layout, pintura (painting) e composição. Vários fatores contribuem para um alto presentation delay:
Tamanho grande do DOM
Um DOM grande ou profundamente aninhado é uma das causas mais comuns de um alto presentation delay. Toda vez que o navegador precisa atualizar o estado visual da página após uma interação, ele deve recalcular estilos, computar o layout e repintar os elementos afetados. O custo de cada uma dessas etapas escala com o número de nós do DOM que são 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 do que 60 elementos filhos por nó pai (veja a auditoria de tamanho de DOM do Lighthouse). Quando o seu DOM excede esses limites, o navegador gasta muito mais tempo no recálculo de estilo e na computação 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 de contêiner. Se esse contêiner tiver 5.000 nós descendentes, o navegador deve recalcular os estilos para potencialmente todos eles, mesmo que apenas alguns elementos mudem visualmente. Esse recálculo de estilo acontece de forma síncrona antes da próxima pintura, aumentando diretamente o presentation delay.
Para técnicas específicas para reduzir seu DOM, leia nosso guia sobre corrigir tamanho excessivo do DOM.
Trabalho de layout excessivo
Layout (também chamado de "reflow") é o processo onde 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 deve realizar o layout antes de poder pintar o quadro atualizado.
Dois padrões são particularmente prejudiciais para o presentation delay:
Layout síncrono forçado (Forced synchronous layout) 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 realizar o layout de forma síncrona, dentro do seu event handler, para retornar um valor preciso. Esse trabalho de layout torna-se então parte do processing time, mas qualquer layout subsequente acionado por novas alterações no DOM torna-se parte do presentation delay.
Layout thrashing é o padrão repetido de escrever no DOM e depois ler propriedades de layout em um loop. Cada leitura força o navegador a recalcular o layout, e cada escrita invalida o layout novamente. Isso pode causar dezenas ou até centenas de cálculos de layout desnecessários por interação. Aqui está 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;
\/\/ Escrita (invalida o layout)
item.style.width = parentWidth + 'px';
});
}
\/\/ BOM: Leituras em lote, depois escritas em lote
function resizeItems() {
const items = document.querySelectorAll('.item');
\/\/ Lê todos os valores primeiro
const widths = Array.from(items).map(
item => item.parentElement.offsetWidth
);
\/\/ Depois escreve todos os valores
items.forEach((item, i) => {
item.style.width = widths[i] + 'px';
});
}
Renderização no lado do cliente em Single Page Applications (SPAs)
A renderização de HTML no lado do cliente pode impactar significativamente o presentation delay, particularmente em Single Page Applications (SPAs). Quando uma interação do usuário aciona uma mudança de rota ou uma grande atualização de UI, o framework SPA deve:
- Rodar o algoritmo de diffing do DOM virtual para determinar o que mudou
- Aplicar as mutações de DOM resultantes ao DOM real
- Acionar o recálculo de estilo e o layout para todos os elementos afetados
- Pintar o quadro atualizado
Em aplicações React, o processo de reconciliação do DOM virtual faz parte do processing time, mas as mutações de DOM resultantes e seu custo de renderização caem no presentation delay. Quanto mais nós de DOM sua árvore de componentes produz, mais cara é 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 tanto da reconciliação quanto da renderização do navegador.
- Use bibliotecas de virtualização (como
react-windowou@tanstack/react-virtual) para listas longas, para que o DOM contenha apenas os itens visíveis.
Reduzindo o presentation delay
Minimize o tamanho do DOM
A maior vitória para o presentation delay é manter seu DOM pequeno:
- Remova elementos HTML não utilizados, especialmente divs de contêiner 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.
\/\/ Virtualize 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 renderização lenta de conteúdo fora da tela
A propriedade CSS content-visibility diz ao navegador para pular a renderização de 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, limitando o escopo do recálculo de estilo e do layout à porção visível da página.
\/* Aplique content-visibility a seções abaixo da dobra *\/
.below-fold-section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
\/* Aplique 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 possa calcular o tamanho da barra de rolagem corretamente sem renderizar o conteúdo. Isso evita desvios de layout quando o usuário rola e o conteúdo se torna visível.
Para mais estratégias de otimização de CSS que reduzem o custo de renderização, veja o nosso guia sobre remover CSS não utilizado.
Minimize o trabalho de layout acionado por interações
Ao projetar interações, prefira propriedades CSS que não acionem layout. Propriedades como transform e opacity podem ser tratadas pelo compositor da GPU sem acionar layout ou pintura (paint). Em vez de animar top, left, width, ou height, use transform: translate() e transform: scale(). Para a lista completa de propriedades CSS que acionam layout, veja o guia de performance de renderização do web.dev.
Use a propriedade CSS will-change para dar uma dica ao navegador de que um elemento será animado. Isso permite que o navegador crie uma camada de compositor separada para o elemento, isolando sua renderização do resto da página:
\/* Promova elementos para sua própria camada de compositor *\/
.animated-element {
will-change: transform, opacity;
}
\/* Alterne 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 longos presentation delays
Para identificar longos presentation delays, você pode usar o perfilador de performance 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 presentation delay. Ao examinar as atualizações de renderização que ocorrem após o término dos event handlers, você pode identificar quaisquer gargalos que contribuam para um longo presentation delay. Procure por entradas grandes de "Recalculate Style", "Layout", e "Paint" na linha do tempo. Estas representam o trabalho que o navegador faz durante a fase de presentation delay.

Identificando o presentation delay com dados de RUM
Medindo o presentation delay com Long Animation Frames (LoAF)
A API Long Animation Frames (LoAF) mostra exatamente o que causa atrasos na renderização durante as interações do usuário. A API fornece dados de tempo para separar o processing time do presentation delay e identificar quais scripts retardam a renderização.
As principais propriedades do LoAF para entender o presentation delay são:
renderStart: quando o navegador iniciou a fase de renderização (recálculo de estilo, layout, pintura)styleAndLayoutStart: quando a computação de estilo e layout começouduration: duração total do quadro de animação longoblockingDuration: quanto do quadro foi bloqueado por scripts
O LoAF está atualmente disponível apenas no Chromium (Chrome 123+). Para outros navegadores, use os rastros 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 quadro representa o custo de renderização puro, que é o presentation delay. Aqui está como observar e registrar esses dados:
\/\/ Medir o presentation delay 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('Presentation delay breakdown:', {
totalDuration: entry.duration,
renderStart: entry.renderStart,
styleAndLayoutStart: entry.styleAndLayoutStart,
estimatedPresentationDelay: presentationDelay,
scriptCount: entry.scripts.length
});
}
}
});
observer.observe({
type: 'long-animation-frame',
buffered: true
});
Ferramentas de RUM como o CoreDash integram dados de LoAF e mostram quais scripts e alterações de DOM causam atrasos na renderização, com atribuição completa de scripts.
Explore as outras fases do INP
Para colocar seu INP sob controle, aborde também as outras duas fases:
- Input Delay: Minimize o tempo de espera antes que os manipuladores de eventos comecem a ser executados. O input delay é tipicamente a menor fase, mas apresenta picos durante a inicialização da página, quando a thread principal está ocupada.
- Processing Time: Otimize o código do event handler que roda durante a interação. Na maioria das páginas, é aqui que a maior parte do seu esforço de otimização compensa.
Para um fluxo de trabalho de diagnóstico completo, veja o nosso guia sobre como encontrar e corrigir problemas de INP. Para estratégias adicionais de otimização de renderização, explore nossos guias sobre corrigir tamanho excessivo do DOM e remover CSS não utilizado. Retorne à página principal do INP para a visão geral completa.
Your Lighthouse score is not the full picture.
Lab tests run on fast hardware with a stable connection. I analyze what your actual visitors experience on real devices and real networks.
Analyze Field Data
