Quando você clica em um botão e nada parece acontecer, uma breve pausa faz a página responder.
As pessoas não relatam isso como um bug, mas tendem a se sentir mais frustradas do que quando chegaram. Essa pequena pausa é exatamente o que a métrica Interação com a próxima pintura (INP) foi projetada para medir. Desde que substituiu o First Input Delay como Core Web Vital em março de 2024, tornou-se uma das métricas mais desafiadoras para muitas equipes de desenvolvimento abordarem.
Ao contrário do Large Contentful Paint e do Cumulative Layout Shift, que muitas vezes podem ser melhorados com otimizações de imagem e caixas reservadas, o INP está profundamente conectado ao seu JavaScript, manipuladores de eventos e pipeline de renderização.
Este guia explica como identificar as interações que causam atrasos e as correções reais que produzem mudanças reais.
O que o INP realmente mede
O INP observa cada clique, toque e pressionamento de tecla durante uma visita e relata o mais lento.
Ele mede o tempo entre a entrada do usuário e o navegador renderizando o próximo quadro. Em páginas com muitas interações, um valor extremo é ignorado.
Os limites de desempenho do Google são simples: 200 milissegundos ou menos é excelente, 200 a 500 milissegundos precisam de melhorias e qualquer coisa acima de 500 milissegundos é ruim.
Esses limites são baseados no 75º percentil de visitas reais de usuários, portanto, o desempenho em um laptop rápido não conta toda a história. Em vez disso, o telefone lento com uma conexão ruim é o que importa.
Cada interação é dividida em três partes distintas:
• Atraso de entrada: o tempo antes que o manipulador de eventos possa ser iniciado, geralmente porque o thread principal está ocupado com outra tarefa.
• Tempo de processamento: o tempo que o manipulador de eventos leva para ser executado.
• Atraso na apresentação: o tempo que o navegador gasta recalculando estilos, organizando a página e pintando.
Entender qual parte da interação está causando a lentidão ajuda a economizar tempo e esforço, já que cada parte pode ser abordada de forma diferente.
Comece com dados de usuários reais, não com suposições
Ferramentas baseadas em laboratório, como o Lighthouse, não podem interagir com um site da mesma forma que os usuários reais, portanto, podem perder completamente os problemas de INP.
É melhor começar com dados de usuários reais. O relatório Chrome UX e o relatório Core Web Vitals no Search Console podem mostrar se há problemas e em quais URLs.
Para determinar qual interação é lenta, use a biblioteca web-vitals de código aberto do Google e sua construção de atribuição:
import { onINP } from 'web-vitals/attribution';
onINP(({ value, attribution }) => {
navigator.sendBeacon('/vitals', JSON.stringify({
value,
target: attribution.interactionTarget,
type: attribution.interactionType,
inputDelay: attribution.inputDelay,
processing: attribution.processingDuration,
presentation: attribution.presentationDelay,
}));
});
```
Over a few days, this gives you a ranked list of the elements users struggle with and which of the three phases is to blame.
That list becomes your to-do list. Reproduce the worst offender in Chrome Dev Tools using CPU throttling at 4x or 6x slowdown, record a trace in the Performance panel, and look for the long, red-flagged tasks around your click.
Fix 1: Break Up Long Tasks
The browser cannot respond to a click while it is busy running a large amount of JavaScript.
Any task lasting longer than 50 milliseconds is considered long, and the longer it runs, the worse the input delay for any interaction that happens during that time.
The solution is to break big jobs into smaller pieces and allow the browser to catch its breath in between.
Modern browsers provide `scheduler.yield()` for this, which hands control back to the browser and resumes your work with priority:
```javascript
async function processItems(items) {
for (const item of items) {
handle(item);
if ('scheduler' in window && 'yield' in scheduler) {
await scheduler.yield();
} else {
await new Promise(r => setTimeout(r, 0));
}
}
}
```
Yielding after each item is unnecessary.
In practice, yield after a few milliseconds of work, for instance by checking `performance. now()` against a deadline. The `set Timeout` fallback ensures compatibility with older browsers.
Fix 2: Do Less Inside the Event Handler
An event handler should only do the minimum required to provide immediate visual feedback to the user.
Everything else can be done later. Developers often stuff state updates, analytics calls, logging, and storage writes into a single click handler. The user only needs the visual response; the rest can wait.
A helpful way to think about this is to separate urgent tasks from deferrable ones.
Update the button state and open the menu immediately. Return only the final result and avoid any unnecessary system messages.
After the button is clicked, send the analytics event:
```javascript
button.addEventListener('click', () => {
openMenu();
requestAnimationFrame(() => {
setTimeout(() => trackEvent('menu_open'), 0);
});
});
Esse padrão de uso request Animation Frame seguido pela set Timeout garante que o navegador conclua a renderização antes de manipular o evento analítico.
Pode parecer estranho, mas atrasa o trabalho de forma confiável até depois do próximo quadro. Além disso, tenha cuidado com leituras e gravações síncronas em local Storage em manipuladores de eventos, pois podem bloquear o thread principal e acumular mais rapidamente do que o esperado.
Correção 3: Reduza o custo de renderização
Às vezes, seu JavaScript é rápido, mas a página ainda parece lenta.
Isso é chamado de atraso de apresentação e geralmente é causado por muito DOM ou muito trabalho de layout, ou ambos.
Várias mudanças podem melhorar muito o desempenho:
- Reduza o tamanho do DOM: páginas com milhares de nós DOM tornam cada recálculo de estilo mais caro.
Use a virtualização para listas longas para que apenas as linhas visíveis existam no DOM.
- Evite trabalho fora da tela: use a propriedade CSS
content-visibility: autopara permitir que o navegador pule as seções de renderização que não estão na tela no momento.
Combine-o com contain-intrinsic-size para evitar que as barras de rolagem saltem.
- Evite a destruição do layout: lendo um valor de layout como
off set Heightlogo após alterar um estilo força o navegador a recalcular imediatamente.
Em vez disso, agrupe todas as leituras do layout primeiro e depois execute todas as gravações.
- Anime propriedades baratas: use propriedades como
transformeopacityque pode ser animado sem causar recálculos de layout.
Em um rastreamento de desempenho, blocos roxos largos rotulados como “Recalcular estilo” ou “Layout” após o manipulador são um sinal de que você está enfrentando esse problema.
Correção 4: mantenha scripts de terceiros sob controle
Gerenciadores de tags, widgets de bate-papo, ferramentas de teste A/B e scripts de anúncios competem pelo mesmo tópico principal do seu código.
Esses scripts são uma das principais causas de alto atraso de entrada. Como você não controla o código deles, a principal correção geralmente é quando eles são carregados, não como funcionam.
Carregue-os usando a sync ou deferatrase scripts não essenciais até depois da primeira interação do usuário ou durante o tempo ocioso da página e audite-os regularmente.
É surpreendentemente comum encontrar scripts que foram adicionados a uma campanha anos atrás e que não são mais necessários. A remoção desses widgets pode melhorar significativamente o desempenho.




