Performance

INP alto: como diagnosticar interações lentas e reduzir trabalho na thread principal

Aprenda a reproduzir, decompor e corrigir Interaction to Next Paint, identificando atraso de entrada, processamento e apresentação visual.

Leitura executiva

Principais conclusões

  • INP exige interações reais; Lighthouse não o reproduz sozinho.
  • Descubra qual interação e qual fase dominam a latência.
  • Quebre tarefas longas e atualize apenas a parte necessária da interface.
  • Ofereça feedback visual rápido sem esconder processamento excessivo.

Interaction to Next Paint (INP) mede quanto tempo uma página leva para apresentar resposta visual depois de interações como clique, toque e teclado. Um INP alto pode acontecer no carregamento, numa busca, ao abrir um menu, escolher uma variação, adicionar ao carrinho ou preencher um formulário.

O limite recomendado é de 200 milissegundos no percentil 75. Como a métrica depende de uso real ao longo da visita, um teste que apenas carrega a página não consegue diagnosticar a experiência inteira.

Entenda as três fases de uma interação

Atraso de entrada

É o tempo entre a ação do usuário e o início do código que trata o evento. O navegador pode estar ocupado com outra tarefa: execução de JavaScript, callback de terceiro, cálculo de estilo ou outro trabalho na thread principal.

Processamento

É o tempo gasto nos handlers e no trabalho que eles disparam. Validação pesada, serialização, loops, filtros grandes, atualizações de estado e renderizações podem dominar essa fase.

Atraso de apresentação

Depois do código, o navegador ainda precisa calcular estilos, layout e pintura. Alterar uma grande parte do DOM ou forçar leituras e escritas alternadas pode adiar o próximo frame.

O diagnóstico precisa indicar qual fase é dominante. “Reduzir JavaScript” é direção, não causa.

Comece com dados de campo

Dados públicos podem indicar que a origem ou grupo de páginas falha INP, mas normalmente não dizem qual botão foi lento. Instrumentação própria com a biblioteca web-vitals pode registrar a métrica e atributos de diagnóstico, respeitando privacidade e volume.

Combine o sinal com analytics:

  • template e URL;
  • dispositivo;
  • etapa da jornada;
  • versão da aplicação;
  • interações mais frequentes;
  • erro ou abandono próximo.

Não capture texto digitado ou dados pessoais. O objetivo é identificar componentes e tipos de evento.

Reproduza interações importantes

Liste ações críticas por template:

  • abrir navegação;
  • aceitar ou rejeitar consentimento;
  • usar busca e filtros;
  • selecionar variação;
  • adicionar item ao carrinho;
  • avançar no checkout;
  • enviar formulário;
  • expandir FAQ;
  • trocar aba ou modal.

No painel de Performance do Chrome, grave a ação em um dispositivo representativo ou com desaceleração controlada. Repita mais de uma vez. A primeira interação pode incluir inicialização que as seguintes não executam.

Encontre tarefas longas

Uma tarefa longa ocupa a thread principal por mais tempo do que um frame responsivo tolera. Durante esse período, novas entradas esperam.

Investigue:

  • avaliação de bundles;
  • hidratação de árvore grande;
  • gerenciadores de tags;
  • widgets de chat;
  • testes A/B;
  • mapas e players;
  • bibliotecas de componentes;
  • manipulação de listas grandes;
  • processamento de JSON;
  • validações complexas.

Quebrar uma tarefa permite que o navegador processe entradas e renderize entre blocos. Técnicas incluem dividir trabalho, agendar partes não urgentes e mover computação adequada para Web Workers.

Reduza JavaScript inicial e tardio

INP não é apenas uma métrica de carregamento. Scripts carregados depois podem competir com interações.

Pergunte para cada componente:

  • precisa hidratar;
  • pode ser HTML e CSS;
  • pode carregar após interação;
  • pode executar no servidor;
  • está presente em páginas onde não é usado;
  • duplica funcionalidade nativa do navegador;
  • traz dependência muito maior que sua função.

Conteúdo editorial, navegação simples, details/summary e formulários nativos podem reduzir a superfície de JavaScript sem sacrificar experiência.

Atualize menos elementos

Um clique pequeno não deveria renderizar a página inteira. Revise limites de componentes, seletores de estado e dependências de efeitos.

Problemas comuns:

  • contexto global atualizado a cada tecla;
  • lista inteira recalculada para uma mudança local;
  • chave instável recriando componentes;
  • efeitos que atualizam estado em cadeia;
  • leitura de layout depois de cada escrita;
  • tabelas grandes sem virtualização quando ela é necessária.

Meça antes de aplicar memoização em todo lugar. Cache e memoização também têm custo e complexidade.

Controle eventos de alta frequência

input, scroll, pointermove e resize podem disparar muitas vezes. Use uma estratégia compatível com a experiência:

  • throttle para limitar frequência contínua;
  • debounce quando a ação pode esperar o usuário pausar;
  • requestAnimationFrame para trabalho visual alinhado ao frame;
  • listeners passivos em cenários de rolagem compatíveis;
  • cancelamento de requisições obsoletas.

Numa busca, a interface pode atualizar o texto imediatamente e adiar a requisição. Isso preserva feedback sem disparar trabalho caro a cada tecla.

Mostre feedback antes do trabalho não visual

Se a ação precisa iniciar processamento ou rede, confirme o clique rapidamente:

  • altere o estado do botão;
  • mostre progresso;
  • atualize a seleção;
  • mantenha foco e anúncio acessível;
  • adie analytics e tarefas secundárias.

Feedback visual não corrige uma thread bloqueada, mas uma arquitetura que renderiza o estado mínimo primeiro pode reduzir o atraso percebido e a fase de apresentação.

Revise terceiros com critério comercial

Scripts de terceiros competem pela mesma thread. Crie um inventário com proprietário, finalidade, páginas, bytes, tempo de CPU e impacto de remoção.

Opções:

  • carregar somente nas páginas necessárias;
  • adiar até consentimento ou interação;
  • substituir por integração de servidor;
  • reduzir tags duplicadas;
  • remover fornecedores sem uso comprovado;
  • definir orçamento de CPU, não apenas de bytes.

Não remova instrumentação crítica sem alinhar com analytics, marketing e jurídico. A recomendação precisa considerar valor e risco.

Use TBT como pista, não como substituto

Lighthouse reporta Total Blocking Time (TBT) durante a janela de laboratório. Reduzir tarefas longas que pioram TBT pode ajudar INP, mas a relação não é garantida. A interação lenta pode acontecer minutos depois, num componente que o Lighthouse nunca acionou.

O fluxo correto é: campo confirma INP, laboratório e profiling reproduzem interações, a correção reduz trabalho e o campo verifica tendência.

Escreva uma tarefa verificável

Observação: ao aplicar filtro em mobile, a interação leva cerca de 480 ms no perfil; 300 ms são consumidos recalculando e renderizando todos os cards. Ação: mover filtragem simples para dados já normalizados, atualizar somente a lista e adiar analytics. Aceite: seleção recebe feedback imediato, resultado permanece correto e a mediana da interação em cinco perfis fica abaixo de 200 ms no dispositivo de teste.

Depois do deploy, acompanhe erros, acessibilidade e conversão. Uma interface pode ficar rápida e funcionalmente incorreta se a otimização eliminar validações necessárias.

INP melhora quando o time trata tempo de CPU e escopo de atualização como recursos finitos. A pergunta não é só quanto JavaScript existe, mas quando ele executa, por que executa e se está no caminho da ação do usuário.

Respostas diretas

Perguntas frequentes

Qual é um bom INP?

A recomendação atual é INP de até 200 milissegundos no percentil 75 das visitas, separado entre mobile e desktop.

TBT e INP são a mesma métrica?

Não. Total Blocking Time é uma métrica de laboratório ligada a tarefas longas durante o carregamento. Pode indicar risco, mas INP mede interações reais durante a visita.

Debounce sempre melhora INP?

Não. Pode reduzir chamadas repetidas, mas também atrasar a resposta percebida. Use conforme o tipo de evento e mantenha feedback imediato quando necessário.