Pular para o conteúdo
Zumkai

INP e animação: o que realmente conta para a métrica

Rolagem não entra no INP. O que entra é a animação rodando no momento do clique. A tabela do que toca cada fase, e os 50% contra 1% de quadros.

  • inp
  • core web vitals
Card comparando os quadros perdidos ao animar top e left, 50%, contra animar transform, 1%.
Sumário
  1. O que o INP mede, nas três fases
  2. Por que a rolagem ficou de fora, e o que isso libera
  3. O que realmente custa: a animação que roda no clique
  4. Compositor contra thread principal, com o número do Chrome
  5. A tabela: qual técnica toca qual fase
  6. will-change é último recurso, não otimização
  7. O que os dados de campo mostram
  8. Como diagnosticar no seu site
  9. Como este blog trata isso
  10. Perguntas frequentes
  11. O que levar

A animação que mais assusta quem faz motion não está no seu INP.

Rolagem não conta. A métrica observa clique, toque e tecla, e ignora scroll, hover e zoom. Isso está na definição, não é interpretação. Então aquele reveal caprichado que dispara ao rolar a página, o parallax do hero, a barra de progresso que acompanha a leitura: nada disso entra diretamente na conta.

O que entra é outra coisa, e é bem mais específica: a animação que está rodando no instante em que a pessoa clica.

Este post separa uma da outra. Com a definição na fonte, o número oficial do Chrome para o custo de animar errado, e uma tabela que mapeia cada técnica de motion contra a fase do INP que ela toca. É a continuação natural de a fundação de scroll, agora pelo lado da métrica.

O que o INP mede, nas três fases

INP é o tempo entre a interação e o momento em que o navegador entrega o próximo quadro. Esse intervalo se divide em três partes, e saber qual delas você está piorando é o que torna o diagnóstico possível (web.dev).

As três fases de uma interação medida pelo INP O INP soma três fases: atraso de entrada, que é a espera até o handler começar; duração de processamento, que é a execução dos handlers; e atraso de apresentação, que é o tempo até o navegador pintar o próximo quadro. O limiar de bom é 200 milissegundos no percentil 75. Do clique até o próximo quadro atraso de entrada espera pelo thread processamento os handlers rodando atraso de apresentação renderizar e pintar A animação entra aqui, na terceira fase Bom: ≤ 200 ms · precisa melhorar: até 500 · ruim: acima de 500 medido no percentil 75 do tráfego real
Fonte: documentação do INP em web.dev. Os limiares valem no percentil 75.

Atraso de entrada é a espera até o handler começar a rodar, normalmente porque o thread principal está ocupado. Duração de processamento é a execução dos handlers daquele quadro. Atraso de apresentação é o que vem depois: o navegador precisa recalcular o que mudou e pintar.

O limiar de bom é 200 milissegundos, medido no percentil 75 do tráfego real. Acima de 500 é ruim.

E há a parte que muda tudo para quem faz motion:

Conta para o INPNão conta
Clique de mouseRolagem
Toque na telaHover
Tecla pressionadaZoom

O INP substituiu o FID, que media só a primeira interação e só o atraso de entrada. A troca importa porque agora toda interação da visita é observada, não apenas a de abertura.

Por que a rolagem ficou de fora, e o que isso libera

Rolagem não é interação para efeito de INP. A consequência prática é grande e quase ninguém a enuncia: animação de scroll não aparece na métrica.

Um reveal que dispara quando a seção entra na tela, um parallax, uma barra de progresso de leitura, uma imagem que escala conforme a página desce. Se essas animações rodam durante a rolagem e a pessoa não está clicando, elas não têm como piorar o INP, porque não existe interação sendo medida naquele momento.

Isso não as torna gratuitas. Animação mal feita durante o scroll causa engasgo visível, e engasgo é problema mesmo sem métrica que o meça. A diferença é de diagnóstico: se o seu INP está ruim, procurar a culpa no parallax é procurar no lugar errado.

A distinção muda a prioridade do trabalho. Os oito padrões de ScrollTrigger que cobrem a maior parte dos casos são todos de rolagem, e nenhum deles precisa ser sacrificado por causa do INP. Se eles engasgam, o problema é de fluidez e se resolve com propriedade de compositor. Se o INP está ruim, a causa está em outro lugar da página.

As técnicas de rolagem sem JavaScript, tratadas em animação de scroll sem JavaScript, rodam no compositor justamente para não engasgar. Elas resolvem o problema de fluidez. O INP é outro problema, e é o assunto daqui em diante.

O que realmente custa: a animação que roda no clique

O caso que cobra é este: existe animação em andamento, e a pessoa clica.

O clique chega, o handler roda, e então o navegador precisa entregar o próximo quadro. Só que ele já tinha trabalho de renderização na fila por causa da animação. Esse trabalho entra na terceira fase, o atraso de apresentação, e o relógio do INP continua correndo até o quadro sair.

A aritmética do quadro explica por que isso pesa. A 60 quadros por segundo, o navegador tem cerca de 16,7 milissegundos para produzir cada um, e nesse orçamento cabe tudo: estilo, layout, pintura e composição. Uma animação que dispara layout consome parte desse tempo em todo quadro enquanto roda. Quando o clique chega, ele não encontra um thread ocioso: encontra um thread que já está com a agenda cheia até o fim da animação.

O limiar de 200 milissegundos equivale a cerca de doze quadros. Parece muito, e é — o que faz um INP ruim não é um quadro caro, é uma fila deles. Por isso animação de dois segundos com layout a cada quadro é bem pior que uma operação única cara: ela mantém o thread ocupado por cento e vinte quadros seguidos.

Três situações concentram os problemas:

A animação roda enquanto o usuário clica. Um carrossel em rotação automática, um contador animado, um loop decorativo. Se a animação está no thread principal, ela disputa com o clique.

O clique dispara a animação. Aqui o custo aparece antes, na duração de processamento: o handler que inicia a animação faz trabalho, e só depois vem a renderização. Menus que abrem, acordeões, modais e transições de página caem nesse grupo.

A biblioteca carrega no clique. Se a animação depende de um pacote que só é buscado na interação, o custo aparece na primeira fase, no atraso de entrada, e costuma ser o pior dos três.

Compositor contra thread principal, com o número do Chrome

A diferença entre animar certo e errado tem medida oficial, e ela é maior do que a maioria imagina.

Segundo o guia de performance de animação do Chrome, animar com top e left resulta em 50% dos quadros perdidos. A mesma animação feita com transform perde 1% (web.dev).

Quadros perdidos por propriedade animada Animar com as propriedades top e left resulta em 50% dos quadros perdidos. A mesma animação com transform perde apenas 1% dos quadros, porque roda no compositor sem disparar layout. Quadros perdidos na mesma animação top / left 50% dispara layout no thread principal transform 1% roda no compositor, sem layout
Fonte: guia de performance de animação do Chrome, em web.dev.

A razão é simples. transform e opacity animam no compositor sem disparar layout nem paint. Qualquer outra propriedade obriga o navegador a recalcular posições, e esse recálculo acontece no thread principal, exatamente onde o clique precisa ser atendido.

A recomendação da própria documentação é direta: evitar toda propriedade que dispare layout ou paint, a menos que seja realmente necessário.

As trocas que resolvem sem mudar o resultado visual

Quase toda animação que dispara layout tem equivalente no compositor, e a diferença raramente é perceptível para quem olha.

Em vez de animarAnimeObservação
top, left, right, bottomtransform: translate()Mesmo deslocamento, sem layout
width, heighttransform: scale()Escala o conteúdo junto; para caixa que precisa reflow real, não há equivalente
margin, paddingtransform: translate()Se o objetivo é mover, e não empurrar vizinhos
visibility, displayopacity mais pointer-eventsdisplay não anima; a troca também evita salto de layout
background-positiontransform numa camada internaDispara paint, que é menos caro que layout, mas ainda é thread principal
box-shadow, filterpré-renderizar em duas camadas e cruzar opacitySão caros em paint quando animados

Uma exceção honesta: width e height quando o objetivo é realmente empurrar o conteúdo em volta, como num acordeão que abre. Aí não existe substituto: scale deforma o conteúdo e não move os vizinhos. Nesse caso, a saída é limitar a área afetada e aceitar o custo, não fingir que ele não existe.

O catálogo completo de técnicas, com o código de cada uma, está em o guia de motion design para web. Aqui interessa só o critério de escolha.

A tabela: qual técnica toca qual fase

<!-- [UNIQUE INSIGHT] -->

Juntando as duas documentações, dá para mapear cada técnica de motion contra a fase do INP que ela afeta. Essa tabela não existe em lugar nenhum, e é ela que responde a pergunta prática.

TécnicaFase que tocaPor quê
Animação de scrollNenhumaRolagem não é interação medida
Hover com transformNenhumaHover não é interação medida
transform/opacity rodando no cliqueApresentação, poucoTrabalho vai para o compositor
top/left/width/height no cliqueApresentação, muitoDispara layout no thread principal
Animação disparada pelo clique, em JSProcessamento e apresentaçãoO handler roda antes do quadro
Biblioteca carregada no cliqueAtraso de entradaBloqueia antes do handler começar

A leitura que sai daí: a maior parte do motion de um site não aparece no INP. O que aparece é o que coincide com o clique e o que o clique dispara. Se você precisa cortar animação para melhorar a métrica, corte dessas duas categorias, e deixe o resto em paz.

Animação de texto ilustra bem os dois lados: um efeito de entrada disparado por scroll não custa nada à métrica; o mesmo efeito disparado por clique, com a biblioteca sendo carregada na hora, custa nas três fases.

will-change é último recurso, não otimização

Aqui o conselho corrente está errado, e vale dizer com todas as letras.

will-change promove o elemento a uma camada própria, o que tira o trabalho de pintura do thread principal. Isso parece uma otimização de graça, e é assim que a maioria dos textos apresenta.

A documentação do Chrome recomenda o contrário: usar com parcimônia, porque criar camada tem custo próprio e pode gerar outros problemas de performance. A orientação é aplicar depois de constatar o problema, não antes. Quando fizer sentido, aplique ao elemento pouco antes da mudança e remova quando ela terminar.

Onde não há suporte, transform: translateZ(0) força a criação da camada com o mesmo efeito.

A decisão de qual ferramenta usar para animar, tratada em GSAP, Motion ou CSS puro, muda pouco aqui: a regra de propriedade vale igual em qualquer biblioteca. O que muda é quanto JavaScript vem junto, e isso pesa na primeira fase.

O que os dados de campo mostram

A situação real da web tem um contraste que ajuda a calibrar a preocupação.

Pelo capítulo de performance do Web Almanac 2025, com dados do CrUX de julho de 2025, 77% das origens registram bom INP no mobile e 97% no desktop. Nos três Core Web Vitals juntos, passam 48% no mobile e 56% no desktop (Web Almanac).

E, no mesmo relatório: animações não compostas aparecem em 40% das páginas mobile.

MétricaMobileDesktop
Bom INP77%97%
Passam nos três CWV48%56%
Páginas com animação não composta40%

Os dois primeiros números e o terceiro convivem, e a explicação é a tese deste post: a animação fora do compositor só cobra quando coincide com a interação. Quarenta por cento das páginas mobile animam errado, e a maioria delas passa no INP mesmo assim, porque o usuário raramente clica no meio da animação.

Isso não é permissão para animar errado. É a razão de o problema ser difícil de encontrar: ele aparece de forma intermitente, no percentil 75, e some quando você vai reproduzir.

Como diagnosticar no seu site

O roteiro que funciona vai da métrica para a causa, nunca ao contrário.

Comece pelo campo, não pelo laboratório. INP é métrica de usuário real. O Lighthouse não mede INP de campo, e uma sessão sua na sua máquina não representa o percentil 75. Sem dado de campo você está adivinhando.

As três origens de dado de campo, da mais fácil para a mais precisa: o relatório de Core Web Vitals no Search Console, que agrupa páginas por comportamento parecido; o CrUX, que traz o percentil 75 público do seu domínio quando ele tem tráfego suficiente; e a biblioteca web-vitals instalada no site, que é a única que diz qual elemento causou a pior interação. As duas primeiras dizem que existe problema. Só a terceira diz onde.

Identifique a interação culpada. O INP da página é a pior interação, não a média. Vale descobrir qual elemento está por trás dela antes de mexer em qualquer animação.

Separe as três fases. Se o problema está no atraso de entrada, a culpa é de JavaScript bloqueando antes do clique, e animação não tem nada a ver. Se está no processamento, olhe o handler. Só se estiver no atraso de apresentação a animação entra como suspeita.

Só então procure a propriedade. Verifique se o que está animando é transform ou opacity. Qualquer outra coisa é candidata.

Uma observação que orienta a expectativa: o guia oficial de otimização de INP do Google quase não fala de animação. Ele trata de tamanho de DOM, de content-visibility para adiar renderização fora da tela, e de renderização de HTML via JavaScript. Se o seu INP está ruim, a probabilidade de a causa ser JavaScript pesado é bem maior que a de ser o seu parallax.

Como este blog trata isso

<!-- [PERSONAL EXPERIENCE] -->

Preciso começar por uma limitação, porque ela muda o que posso afirmar: este blog não tem analytics de campo instalado. Não existe INP real do ZUMKAI para eu mostrar. O que tenho é medição em laboratório e as decisões de desenho, e é só disso que falo aqui.

As decisões que tomei seguem a regra deste post sem que eu tivesse essa clareza na época. O indicador do sumário do post, que acompanha a leitura, deixou de usar biblioteca de animação e passou a ser transform aplicado direto. O corpo dos artigos e os catálogos usam content-visibility para não renderizar o que está fora da tela. Os gráficos são SVG estático, sem animação nenhuma.

Há uma sobreposição que serve aos dois lados. Respeitar a preferência por menos movimento não é só acessibilidade: para quem ativou essa preferência no sistema, o navegador deixa de fazer o trabalho de renderização das animações desligadas. É o mesmo corte de custo, aplicado exatamente a quem pediu. Uma regra que já deveria existir por respeito acaba entregando desempenho de brinde.

O julgamento explícito: a decisão que mais deve ter ajudado não foi de motion, foi de JavaScript. Tirar biblioteca do caminho do carregamento reduz o atraso de entrada, que é a fase onde o INP costuma se perder. As escolhas de propriedade animada vieram depois, e teriam efeito menor.

E a parte que me incomoda: sem dado de campo, tudo isso é hipótese bem fundamentada, não resultado medido. Instalar a medição está na lista, e até lá qualquer número de INP que eu publicasse sobre o próprio site seria invenção.

Perguntas frequentes

Animação atrapalha o INP?

Só quando roda no momento da interação ou é disparada por ela. A animação entra na terceira fase da métrica, o atraso de apresentação, porque o navegador precisa terminar o trabalho de renderização antes de entregar o quadro. Animação que roda em outro momento não é medida.

Scroll conta para o INP?

Não. O INP observa clique de mouse, toque na tela e tecla pressionada. Rolagem, hover e zoom ficam de fora por definição da métrica. Isso significa que animações de scroll, parallax e reveals não entram diretamente na conta do INP.

Quais propriedades são seguras para animar?

Apenas transform e opacity animam no compositor sem disparar layout ou paint. Na documentação do Chrome, a mesma animação feita com top e left perde 50% dos quadros, enquanto com transform perde 1%. Qualquer propriedade que altere geometria força recálculo no thread principal.

will-change ajuda ou atrapalha?

Depende de como é usado. Ele promove o elemento a uma camada própria, o que ajuda, mas criar camada tem custo e a documentação do Chrome recomenda aplicá-lo com parcimônia, depois de constatar o problema. Aplicar preventivamente em muitos elementos costuma piorar.

Qual o limiar de INP considerado bom?

Até 200 milissegundos, medido no percentil 75 do tráfego real. Entre 200 e 500 fica como "precisa melhorar", e acima de 500 é considerado ruim.

Minha animação é bonita e o INP está ruim. Por onde começo?

Provavelmente não pela animação. Comece separando as três fases no dado de campo: se o problema está no atraso de entrada ou no processamento, a causa é JavaScript, não motion. O guia oficial de otimização de INP trata sobretudo de tamanho de DOM e de renderização por JavaScript, e quase não menciona animação.

O que levar

  • Rolagem, hover e zoom não contam. O INP mede clique, toque e tecla.
  • O que custa é a animação no momento do clique, ou disparada por ele.
  • transform e opacity vão para o compositor. Todo o resto dispara layout.
  • 50% contra 1% de quadros perdidos é a diferença entre top/left e transform.
  • will-change é remédio, não vitamina: só depois de constatar o problema.
  • Antes de culpar o motion, separe as três fases. A causa costuma ser JavaScript.

Se você for mexer em uma coisa só depois de ler isto, troque a propriedade animada. É a mudança mais barata, tem número oficial atrás dela e não custa nada em fluidez — a animação continua igual aos olhos de quem vê.

Leia também