Tempo de Processamento do INP: Causas, Otimização e Exemplos de Código
Aprenda como encontrar e melhorar 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 de um usuário até a próxima atualização visual. O tempo de processamento é a segunda das três fases que compõem o INP, precedido pelo input delay e seguido pelo presentation delay. Se você é novo no INP, leia primeiro nosso guia sobre como identificar e corrigir problemas de INP.
Em suma: 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", "tempo de processamento" e "presentation delay".
O tempo de processamento é um grande contribuinte para o INP total, representando cerca de 40% do atraso em média. Otimizar seus event handlers é 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 alto tempo de processamento?
- Minimize o tempo de processamento
- Quebrando event handlers 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 leva para o navegador executar todos os callbacks de eventos associados após um usuário interagir com uma página web (por exemplo, clicando em um botão ou pressionando uma tecla). Embora sempre haja algum tempo de processamento, problemas de INP ocorrem quando os callbacks de eventos consomem muito tempo de processamento.
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 pesquisa, o tempo de processamento inclui tudo, desde a validação da sua consulta, preparação da requisição da 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 event handlers 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 em termos de otimização de funções de callback (otimizando o tempo de processamento), e eles estão certos. Mas, em termos de importância, o tempo de processamento nem sequer é a parte mais importante a ser melhorada. Ele ainda, em média, compõe cerca de 40% do tempo total do INP.

No 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á os problemas de INP. Você também deve analisar 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 levam, maior o tempo de processamento e, potencialmente, pior a pontuação de INP.
O que causa alto tempo de processamento?
O 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 e não utilizado ou código 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. Múltiplos callbacks de eventos agendados próximos uns dos outros criam uma fila. Se um callback acionado pela interação do usuário ficar preso nessa fila, a resposta parecerá atrasada. Por exemplo, um handler de
pointerdown, um handler demousedowne um handler declickpodem ser disparados sequencialmente para um único clique. - Layout thrashing. Manipulações frequentes do 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 ler e escrever 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 todo o restante do código pode ser executado 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 não utilizado que apenas é executado sem realmente adicionar nada à página ou à UX. A primeira coisa a fazer é garantir que nenhum código desnecessário esteja em execução. Isso pode ser feito por tree shaking, code splitting, inspecionando a cobertura do seu código no Chrome e usando uma boa IDE que indicará o código não utilizado. (Dica de especialista: 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 JavaScript.
- Minimize o tempo de execução de callbacks. Use um profiler de JavaScript para identificar gargalos em seu código e direcionar essas áreas para otimização. Considere técnicas como memoization, pré-cálculo e cache para evitar computações redundantes. (Dica: você pode usar o painel de performance do Chrome para encontrar scripts com longo tempo de execução.)
- Priorize o código crítico e agende outros códigos. Quando o código do callback for otimizado, divida o código entre o que precisa ser executado imediatamente e o 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, fazendo com que o navegador recalcule o layout inúmeras vezes. Para evitar o layout thrashing, faça todas as mudanças de estilo (os "sets") antes de solicitar valores de estilo (os "gets"). Esta abordagem minimiza a frequência de 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 event handlers com setTimeout(0)
Quando você não pode remover ou adiar o código de um event handler, a próxima melhor opção é quebrar o handler em pedaços menores. O padrão setTimeout(callback, 0) permite que você divida 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:
// Antes: um longo event handler bloqueia o próximo paint
button.addEventListener('click', () => {
updateUI(); // Crítico: deve rodar antes do paint
validateForm(); // Importante, mas pode esperar
sendAnalytics(); // Não crítico
syncLocalStorage(); // Não crítico
});
// Depois: quebre em trabalho crítico e adiado
button.addEventListener('click', () => {
updateUI(); // Crítico: roda imediatamente antes do 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() em vez disso (veja a seção abaixo). Para padrões que visam especificamente o tratamento de rolagem via JavaScript, consulte nosso guia dedicado.
Usando requestAnimationFrame para atualizações visuais
Quando o seu event handler precisa acionar uma atualização visual, o requestAnimationFrame() garante que seu código seja executado no momento ideal: logo antes de o navegador realizar seu próximo repaint. Isso é especialmente útil quando você precisa agrupar leituras e gravações no DOM para evitar o layout thrashing.
// Use requestAnimationFrame para agrupar atualizações visuais
button.addEventListener('click', () => {
// Leia as propriedades de layout primeiro (fora do rAF)
const containerWidth = container.offsetWidth;
requestAnimationFrame(() => {
// Escreva propriedades de layout dentro do rAF
items.forEach(item => {
item.style.width = containerWidth + 'px';
});
});
// Agende trabalho não visual para o tempo ocioso
requestIdleCallback(() => {
trackButtonClick();
updateSessionState();
});
});
Este padrão separa as leituras do DOM das gravações no DOM, prevenindo 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
"Priorize o código crítico e agende outros códigos" soa abstrato, então aqui está como isso se parece na prática. Podemos priorizar o código crítico usando requestIdleCallback() e fazendo yield para a thread principal.
Usamos o requestIdleCallback para tarefas menos importantes que não precisam ser executadas imediatamente. Aqui está um exemplo de antes e depois do agendamento de um evento do GTM:
/* antes: executa o código imediatamente */
gtag('event', '<event_name>', {
'event_category': '<event_category>',
});
/* depois: executa o mesmo código durante a ociosidade do navegador */
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 um "yield" para a thread principal depois que o código mais importante for executado, dando ao navegador um momento para realizar a atualização de layout. Aqui está um exemplo de como quebrar tarefas fazendo yield 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() {
// Faça as atualizações de layout mais importantes aqui
await yieldToMain();
// Faça outras tarefas que precisam ser executadas o mais rápido possível após a atualização de layout
}
Agendamento refinado com scheduler.postTask()
A função scheduler.postTask() fornece um agendamento de tarefas mais refinado configurando prioridades, o que ajuda o navegador a priorizar o trabalho para que tarefas de baixa prioridade façam yield para a thread principal. Verifique a tabela de suporte do navegador antes de usar esta API em produção.
A função postTask() aceita três configurações de prioridade: "background" para as 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 certa para cada pedaço de trabalho dentro de seu event handler, você pode garantir que o navegador lide com as interações do usuário de forma responsiva enquanto ainda conclui todas as tarefas necessárias:
// Agende trabalho crítico de UI com alta prioridade
scheduler.postTask(() => {
updateCartBadge();
showConfirmation();
}, { priority: 'user-blocking' });
// Agende sincronização de dados com prioridade média
scheduler.postTask(() => {
syncCartWithServer();
}, { priority: 'user-visible' });
// Agende analytics com baixa prioridade
scheduler.postTask(() => {
gtag('event', 'add_to_cart', { item: productId });
fbq('track', 'AddToCart');
}, { priority: 'background' });
Implicações práticas
Aqui está como abordar a otimização do tempo de processamento no WordPress e 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 event listeners à página que não fazem nada, exceto atrasar o Interaction to Next Paint (INP). Se o seu site WordPress estiver com problemas no INP causados por um longo tempo de processamento, siga estes passos:
- Verifique as configurações do tema. Desmarque opções desnecessárias como "smooth scroll" 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 forem relacionados a plugins, considere encontrar outro plugin que faça aproximadamente a mesma coisa com menos JavaScript.
- Muitas vezes existem scripts personalizados rodando na página. Verifique esses scripts e garanta que eles façam yield para a thread principal com frequência e envolvam os 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 tags não utilizadas ou desnecessárias.
- Use temas leves e limpos. Temas multipropósito que "fazem tudo" tendem a ter mais scripts e event handlers mais pesados.
- Evite page builders, pois eles frequentemente dependem muito do JavaScript para apresentar as páginas ao usuário final.
React / Next.js
Os hooks do React e os recursos de concorrência possibilitam 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 experiência de usuário mais suave, especialmente durante a entrada de dados (input).
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 pesquisa emstartTransitionpara que a digitação na caixa de pesquisa permaneça responsiva.useDeferredValue: Divida sua UI 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 pesquisa.useOptimistic(React 19+): Mostre um estado temporário e otimista enquanto operações assíncronas (como requisições de rede) estão em andamento. Isso mantém a UI 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 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 abranger 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 interruptí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 daquele 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 background.
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 event handlers comecem a ser executados. O input delay representa aproximadamente 18% do tempo total do INP.
- Presentation Delay: Reduza o trabalho de renderização e painting, 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 hub do INP para a visão geral completa.
A performance cai no momento que você para de olhar.
Monto o monitoramento, os budgets e o processo. É isso que separa um fix de uma solução.
Vamos conversar
