Tempo de Processamento do INP: Causas, Otimização e Exemplos de Código
Aprenda como encontrar e resolver problemas de INP causados pelo tempo de processamento

Problemas de Interaction to Next Paint (INP) causados pelo tempo de processamento
Esta página faz parte da nossa série sobre Interaction to Next Paint (INP). O INP mede o tempo total desde a interação do usuário até a próxima atualização visual. O tempo de processamento é a segunda das três fases que compõem o INP, precedida pelo input delay e seguida pelo presentation delay. 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. Esse INP pode ser dividido em 3 componentes: "input delay", "tempo de processamento" e "presentation delay".
O tempo de processamento é um grande contribuinte para o INP total, representando em média cerca de 40% do atraso. Otimizar seus manipuladores de eventos é a maneira mais direta de reduzir o tempo de processamento e melhorar sua pontuação de INP.
DICA DE INP: o tempo de processamento pode ser otimizado executando imediatamente o código importante que precede a atualização de layout e agendando todo o restante do código para ser executado depois disso.
Table of Contents!
- Problemas de Interaction to Next Paint (INP) causados pelo tempo de processamento
- O que é tempo de processamento?
- Tempo de processamento e o INP
- O que causa um tempo de processamento alto?
- Minimize o tempo de processamento
- Quebrando manipuladores de eventos com setTimeout(0)
- Usando requestAnimationFrame para atualizações visuais
- Como priorizar código crítico
- Agendamento refinado com scheduler.postTask()
- Implicações práticas
- Explore as outras fases do INP
O que é tempo de processamento?

O Interaction to Next Paint (INP) pode ser dividido em 3 subpartes: "Input Delay", "Tempo de Processamento" e "Presentation Delay".
O tempo de processamento refere-se ao tempo que o navegador leva para executar todos os callbacks de eventos associados após um usuário interagir com uma página da web (por exemplo, clicando em um botão ou pressionando uma tecla). Embora sempre exista algum tempo de processamento, problemas de INP ocorrem quando os callbacks de eventos consomem tempo de processamento excessivo.
De forma simples: o tempo de processamento é a duração do "trabalho" que acontece em resposta à sua interação. Quando você clica em um botão de busca, o tempo de processamento inclui tudo, desde a validação da sua consulta, preparação da requisição à API, atualização do estado local, acionamento de eventos de analytics e qualquer outro código anexado a esse evento de clique. Cada linha de JavaScript nesses manipuladores de eventos contribui para o tempo de processamento.
Tempo de processamento e o INP
O tempo de processamento pode ser a primeira coisa que vem à mente quando você pensa em otimizar o Interaction to Next Paint. É o "trabalho que precisa ser feito" antes que o layout possa ser atualizado pelo navegador.
Muitos desenvolvedores pensam em melhorar o INP otimizando funções de callback (otimizando o tempo de processamento), e eles estão certos. Mas, em termos de importância, o tempo de processamento não é sequer a parte mais importante a ser melhorada. Ainda assim, em média, ele representa cerca de 40% do tempo total do INP.

Na CoreDash, coletamos milhões de pontos de dados de Core Web Vitals a cada hora. Com base nesses dados, o tempo de processamento representa 40% do Interaction to Next Paint. 40% é muito, mas otimizar apenas o tempo de processamento não resolverá problemas de INP. Você também deve observar o input delay (18%) e o presentation delay (42%).
Exemplo de tempo de processamento: Quando um usuário clica em um botão para enviar um formulário, o código que valida os dados do formulário, os envia para o servidor e lida com a resposta contribui para o tempo de processamento. Quanto mais tempo essas operações levarem, maior será o tempo de processamento e, potencialmente, pior será a pontuação de INP.
O que causa um tempo de processamento alto?
Um alto tempo de processamento tem quatro causas comuns: código desnecessário, código não otimizado, callbacks agrupados e layout thrashing.

- Código desnecessário. Código antigo, não utilizado ou sem relevância imediata para a interação do usuário pode prolongar o tempo de execução do callback. Isso inclui chamadas de analytics, logging e sincronização de estado que não precisam ser concluídas antes do próximo paint.
- Código não otimizado. Código ineficiente (geralmente loops ou buscas ineficientes no DOM) pode fazer com que os callbacks de eventos sejam executados mais lentamente do que o necessário. Um exemplo comum é consultar o DOM dentro de um loop com
document.querySelectorAll()em vez de armazenar o resultado em cache antes do loop. - Callbacks agrupados. Vários callbacks de eventos agendados muito próximos criam uma fila. Se um callback acionado pela interação do usuário ficar preso nessa fila, a resposta parecerá atrasada. Por exemplo, um manipulador
pointerdown, um manipuladormousedowne um manipuladorclickpodem ser acionados sequencialmente para um único clique. - Layout thrashing. Manipulações frequentes no DOM que acionam recálculos de layout podem sobrecarregar o navegador e levar a regressões de desempenho. Isso acontece quando seu código alterna entre leitura e escrita de propriedades de layout dentro de um loop, forçando o navegador a recalcular o layout várias vezes.
Minimize o tempo de processamento

A estratégia é dupla: otimizar o código existente (remover código desnecessário e otimizar o código atual) e distinguir entre o código que precisa ser executado antes e depois da atualização de layout. O código que é crítico para a atualização de layout precisa ser executado primeiro, e todos os outros códigos podem ser executados após a atualização de layout.
- Remova código não utilizado. Embora remover código não utilizado possa parecer óbvio, na maioria dos sites há pelo menos algum código antigo que simplesmente é executado sem realmente adicionar nada à página ou à UX. A primeira coisa a fazer é garantir que não haja código em execução que não seja necessário. Isso pode ser feito por meio de tree shaking, code splitting, inspecionando a cobertura do seu código no Chrome e usando uma boa IDE que indicará códigos não utilizados. (Dica pro: também dê uma olhada crítica nos recursos carregados pelo seu Tag Manager.) Para mais estratégias, veja nosso guia sobre 14 métodos para adiar o JavaScript.
- Minimize o tempo de execução do callback. Use um profiler de JavaScript para identificar gargalos no seu código e focar nessas áreas para otimização. Considere técnicas como memoization, pré-cálculo e cache para evitar cálculos redundantes. (Dica: você pode usar o painel de performance do Chrome para encontrar scripts com longo tempo de execução.)
- Priorize código crítico e agende outros códigos. Quando o código do callback tiver sido otimizado, divida-o entre o código que precisa ser executado imediatamente e o código que pode ser adiado. Dê uma olhada neste exemplo da vida real:

Neste exemplo, os callbacks de eventos do Google Tag Manager e do Facebook são executados antes do código (React) que precede a atualização de layout. A solução é agendar os callbacks do GTM e do Facebook para serem executados quando o navegador estiver ocioso. - Evite layout thrashing ou reflow. O layout thrashing acontece quando atualizações de estilo e leituras de estilo são misturadas em um loop, forçando o navegador a recalcular o layout inúmeras vezes. Para evitar o layout thrashing, faça todas as mudanças de estilo (os "sets") antes de solicitar os valores de estilo (os "gets"). Essa abordagem minimiza a frequência das atualizações de layout, resultando em uma página mais rápida. Por exemplo, em um loop que define a largura de cada parágrafo para corresponder à largura de um elemento, leia a largura do elemento uma vez antes do loop e use esse valor para atualizar as larguras dos parágrafos dentro do loop.
Quebrando manipuladores de eventos com setTimeout(0)
Quando você não pode remover ou adiar o código de um manipulador de eventos, a próxima melhor opção é quebrar o manipulador em pedaços menores. O padrão setTimeout(callback, 0) permite dividir o trabalho em várias tarefas, dando ao navegador a chance de lidar com a atualização de layout entre elas. Aqui está um exemplo prático:
// Before: one long event handler blocks the next paint
button.addEventListener('click', () => {
updateUI(); // Critical: must run before paint
validateForm(); // Important but can wait
sendAnalytics(); // Non-critical
syncLocalStorage(); // Non-critical
});
// After: break into critical and deferred work
button.addEventListener('click', () => {
updateUI(); // Critical: runs immediately before paint
setTimeout(() => {
validateForm();
}, 0);
setTimeout(() => {
sendAnalytics();
syncLocalStorage();
}, 0);
});
A desvantagem do setTimeout(0) é que ele coloca a continuação no final da fila de tarefas. Se outras tarefas já estiverem na fila, o código adiado pode não ser executado imediatamente. Para um comportamento mais previsível, use o scheduler.yield() (veja a seção abaixo). Para padrões que visam especificamente o manuseio de rolagem em JavaScript, consulte nosso guia dedicado.
Usando requestAnimationFrame para atualizações visuais
Quando o seu manipulador de eventos precisar acionar uma atualização visual, o requestAnimationFrame() garante que o seu código seja executado no momento ideal: logo antes de o navegador realizar o próximo repaint. Isso é especialmente útil quando você precisa agrupar leituras e escritas no DOM para evitar o layout thrashing.
// Use requestAnimationFrame to batch visual updates
button.addEventListener('click', () => {
// Read layout properties first (outside rAF)
const containerWidth = container.offsetWidth;
requestAnimationFrame(() => {
// Write layout properties inside rAF
items.forEach(item => {
item.style.width = containerWidth + 'px';
});
});
// Schedule non-visual work for idle time
requestIdleCallback(() => {
trackButtonClick();
updateSessionState();
});
});
Esse padrão separa as leituras do DOM das escritas no DOM, evitando o layout síncrono forçado. A atualização visual é executada no momento ideal no pipeline de renderização do navegador, e o trabalho não visual é executado durante o tempo ocioso.
Como priorizar código crítico
"Priorizar código crítico e agendar outros códigos" soa abstrato, então aqui está como isso funciona na prática. Podemos priorizar o código crítico usando requestIdleCallback() e fazendo o yielding para a thread principal.
Usamos o requestIdleCallback para tarefas menos importantes que não precisam ser executadas imediatamente. Aqui está um exemplo do antes e depois do agendamento de um evento do GTM:
/* before: immediately run code */
gtag('event', '<event_name>', {
'event_category': '<event_category>',
});
/* after: run the same code during browser idle */
requestIdleCallback(() => {
gtag('event', '<event_name>', {
'event_category': '<event_category>',
});
}, { timeout: 1000 });
A desvantagem do requestIdleCallback é que o código pode não ser executado tão rápido quanto você gostaria. Nesse caso, você pode fazer o "yield para a thread principal" após a execução do código mais importante, dando ao navegador um momento para realizar a atualização de layout. Aqui está um exemplo de como dividir as tarefas fazendo o yielding para a thread principal:
async function yieldToMain() {
if ('scheduler' in window && 'yield' in window.scheduler) {
return await window.scheduler.yield();
}
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
}
async function handleClick() {
// Do the most important layout updates here
await yieldToMain();
// Do other tasks that need to run as soon as possible after the layout update
}
Agendamento refinado com scheduler.postTask()
A função scheduler.postTask() fornece um agendamento mais refinado de tarefas definindo prioridades, o que ajuda o navegador a priorizar o trabalho para que as tarefas de baixa prioridade façam o yield para a thread principal. Verifique a tabela de suporte dos navegadores antes de usar essa API em produção.
A função postTask() aceita três configurações de prioridade: "background" para tarefas de prioridade mais baixa, "user-visible" para tarefas de prioridade média e "user-blocking" para tarefas críticas que exigem alta prioridade.
Ao atribuir a prioridade correta a cada parte do trabalho dentro do seu manipulador de eventos, você pode garantir que o navegador lide com as interações do usuário de forma responsiva, ao mesmo tempo em que conclui todas as tarefas necessárias:
// Schedule critical UI work at high priority
scheduler.postTask(() => {
updateCartBadge();
showConfirmation();
}, { priority: 'user-blocking' });
// Schedule data sync at medium priority
scheduler.postTask(() => {
syncCartWithServer();
}, { priority: 'user-visible' });
// Schedule analytics at low priority
scheduler.postTask(() => {
gtag('event', 'add_to_cart', { item: productId });
fbq('track', 'AddToCart');
}, { priority: 'background' });
Implicações práticas
Veja como abordar a otimização do tempo de processamento no WordPress e no React/Next.js.
WordPress
O WordPress oferece controle limitado quando se trata de scripts de terceiros. Muitos scripts são adicionados por meio de plugins. Na maioria das vezes, esses scripts adicionarão ouvintes de eventos (event listeners) à página que não fazem nada além de atrasar o Interaction to Next Paint (INP). Se o seu site em WordPress estiver com problemas de INP causados por um longo tempo de processamento, siga as próximas etapas:
- Verifique as configurações do tema. Desmarque opções desnecessárias como "rolagem suave" ou "menu animado". Configurações como essas tendem a causar problemas de INP.
- Verifique quais scripts são responsáveis pelo longo tempo de processamento (dica: use o painel de performance do Chrome). Se esses scripts estiverem relacionados a plugins, considere encontrar outro plugin que faça aproximadamente a mesma coisa com menos JavaScript.
- Frequentemente, existem scripts personalizados sendo executados na página. Verifique esses scripts e garanta que eles façam o yield para a thread principal com frequência e envolvam callbacks menos importantes em uma função
requestIdleCallback. - Descarregue scripts não utilizados página por página (dica: use
wp_deregister_script). Alguns plugins tendem a injetar scripts em todas as páginas, mesmo quando a funcionalidade não é necessária. - Verifique seu Tag Manager e remova as tags não utilizadas ou desnecessárias.
- Use temas enxutos e limpos. Temas multifuncionais que "fazem de tudo" tendem a ter mais scripts e manipuladores de eventos mais pesados.
- Evite page builders (construtores de páginas), pois eles frequentemente dependem muito do JavaScript para apresentar as páginas ao usuário final.
React / Next.js
Os hooks e recursos de concorrência do React tornam possível reduzir consideravelmente o tempo de processamento do INP. Aqui estão as principais técnicas:
Priorize a interação do usuário com os recursos de concorrência do React:
O React 18 introduziu recursos de concorrência que otimizam a renderização para uma user experience mais fluida, especialmente durante a entrada de dados.
useTransitionestartTransition: Marque atualizações não críticas para renderização posterior. Isso evita que grandes atualizações bloqueiem a interação do usuário. Por exemplo, envolva uma atualização de resultados de busca emstartTransitionpara que a digitação na caixa de busca permaneça responsiva.useDeferredValue: Divida sua interface em seções essenciais e menos críticas. O React pode interromper a renderização das partes menos críticas para uma experiência mais responsiva. Isso é ideal para renderizar listas filtradas ou resultados de busca.useOptimistic(React 19+): Mostre um estado temporário e otimista enquanto as operações assíncronas (como requisições de rede) estão em andamento. Isso mantém a interface responsiva mesmo durante a busca de dados.
Suspense para busca de dados (React 18+)
O Suspense no React 18 pode ser usado para melhorar o INP permitindo que o navegador priorize as interações do usuário e otimize a renderização. Enquanto o React 16 introduziu o Suspense para code splitting, o React 18 estende essa funcionalidade para englobar a busca de dados.
- Um componente de fallback, como um indicador de carregamento, é exibido enquanto os dados carregam.
- Assim que os dados chegam, o React retoma a renderização do componente suspenso.
- O Suspense, combinado com a renderização interrompível no Concurrent React, prioriza as interações do usuário. Se um usuário interage com um componente suspenso, o React prioriza a renderização desse componente, mantendo a responsividade.
Esses recursos ajudam o React a priorizar as interações do usuário em relação ao trabalho de renderização em segundo plano.
Explore as outras fases do INP
O tempo de processamento é apenas uma parte do Interaction to Next Paint. Para otimizar totalmente suas pontuações de INP, você também deve abordar as outras duas fases:
- Input Delay: Minimize o tempo de espera antes que os manipuladores de eventos comecem a ser executados. O input delay representa aproximadamente 18% do tempo total do INP.
- Presentation Delay: Reduza o trabalho de renderização e pintura que representa aproximadamente 42% do tempo total do INP.
Para um fluxo de trabalho de diagnóstico completo, veja nosso guia sobre como encontrar e corrigir problemas de INP e retorne à página central do INP para uma visão geral completa.
Find out what is actually slow.
I map your critical rendering path using real field data. You get a clear answer on what blocks LCP, what causes INP spikes, and where layout shifts originate.
Book a Deep Dive
