Saiba como otimizar a Interaction to Next Paint do seu site.
Publicado em: 19 de maio de 2023, última atualização: 2 de setembro de 2025
A Interaction to Next Paint (INP) é uma métrica estável das Core Web Vitals que avalia a capacidade de resposta geral de uma página às interações do usuário, observando a latência de todas as interações qualificadas que ocorrem durante a visita de um usuário a uma página. O valor final da INP é a interação mais longa observada (às vezes, ignorando os valores atípicos).
Para oferecer uma boa experiência ao usuário, os sites devem buscar uma Interaction to Next Paint de 200 milissegundos ou menos. Para atingir essa meta para a maioria dos usuários, um bom limite a ser medido é o 75º percentil de carregamentos de página, segmentado em dispositivos móveis e dispositivos desktop.
Dependendo do site, pode haver poucas ou nenhuma interação, como páginas com texto e imagens, mas poucos ou nenhum elemento interativo. Ou, no caso de sites como editores de texto ou jogos, pode haver centenas ou até milhares de interações. Em ambos os casos, quando há um INP alto, a experiência do usuário fica em risco.
Melhorar a INP exige tempo e esforço, mas o resultado é uma experiência do usuário melhor. Neste guia, vamos analisar um caminho para melhorar a INP.
Descobrir o que está causando um INP ruim
Antes de corrigir interações lentas, você precisa de dados para saber se o INP do seu site é ruim ou precisa de melhorias. Depois de ter essas informações, você pode ir para o laboratório para começar a diagnosticar interações lentas e trabalhar em uma solução.
Encontrar interações lentas no campo
O ideal é que sua jornada de otimização da INP comece com dados de campo. Na melhor das hipóteses, os dados de campo de um provedor de monitoramento de usuários reais (RUM, na sigla em inglês) fornecem não apenas o valor da INP de uma página, mas também dados de contexto que destacam qual interação específica foi responsável pelo valor da INP, se a interação ocorreu durante ou após o carregamento de página, o tipo de interação (clique, pressionamento de tecla ou toque) e outras informações valiosas.
Se você não estiver usando um provedor de RUM para receber dados de campo, o guia de dados de campo da INP recomenda usar o PageSpeed Insights para conferir os dados do Chrome User Experience Report (CrUX) e preencher as lacunas. O CrUX é o conjunto de dados do Google do programa Core Web Vitals e fornece um resumo de alto nível das métricas de milhões de sites, incluindo a INP. No entanto, o CrUX geralmente não fornece os dados de contexto que você receberia de um provedor de RUM para ajudar a analisar problemas. Por isso, recomendamos que os sites usem um provedor de RUM sempre que possível ou implementem a própria solução de RUM para complementar o que está disponível no CrUX.
Diagnosticar interações lentas no laboratório
O ideal é começar a testar no laboratório quando você tiver dados de campo que sugiram interações lentas. Na ausência de dados de campo, existem algumas estratégias para identificar interações lentas no laboratório. Essas estratégias incluem seguir fluxos do usuário comuns e testar interações ao longo do caminho, além de interagir com a página durante o carregamento, quando a linha de execução principal costuma estar mais ocupada, para identificar interações lentas durante essa parte crucial da experiência do usuário.
Otimizar interações
Depois de identificar uma interação lenta e conseguir reproduzi-la manualmente no laboratório, a próxima etapa é otimizá-la.
As interações podem ser divididas em três subpartes:
- O atraso de entrada, que começa quando o usuário inicia uma interação com a página e termina quando os callbacks de evento da interação começam a ser executados.
- A duração do processamento, que consiste no tempo que os callbacks de eventos levam para serem concluídos.
- O atraso de apresentação, que é o tempo que o navegador leva para apresentar o próximo frame que contém o resultado visual da interação.
A soma dessas três subpartes é a latência total da interação. Cada subparte de uma interação contribui com algum tempo para a latência total da interação. Por isso, é importante saber como otimizar cada parte da interação para que ela seja executada no menor tempo possível.
Identificar e reduzir a latência na entrada
Quando um usuário interage com uma página, a primeira parte dessa interação é o atraso de entrada. Dependendo de outras atividades na página, os atrasos de entrada podem ser consideráveis. Isso pode ser devido à atividade que ocorre na linha de execução principal (talvez devido ao carregamento, análise e compilação de scripts), ao processamento de busca, às funções de timer ou até mesmo a outras interações que ocorrem em rápida sucessão e se sobrepõem.
Seja qual for a origem do atraso de entrada de uma interação, é importante reduzi-lo ao mínimo para que as interações possam começar a executar callbacks de eventos o mais rápido possível.
A relação entre a avaliação de scripts e as tarefas longas durante a inicialização
Um aspecto crítico da interatividade no ciclo de vida da página é durante a inicialização. Quando uma página é carregada, ela é renderizada inicialmente, mas é importante lembrar que o fato de uma página ter sido renderizada não significa que ela terminou de ser carregada. Dependendo de quantos recursos uma página precisa para se tornar totalmente funcional, é possível que os usuários tentem interagir com ela enquanto ela ainda está carregando.
Uma coisa que pode estender o atraso de entrada de uma interação enquanto uma página é carregada é a avaliação de script. Depois que um arquivo JavaScript é buscado na rede, o navegador ainda tem trabalho a fazer antes que o JavaScript possa ser executado. Esse trabalho inclui analisar um script para verificar se a sintaxe é válida, compilá-lo em bytecode e, por fim, executá-lo.
Dependendo do tamanho de um script, esse trabalho pode introduzir tarefas longas na linha de execução principal, o que atrasa a resposta do navegador a outras interações do usuário. Para manter a página responsiva à entrada do usuário durante o carregamento, é importante entender o que você pode fazer para reduzir a probabilidade de tarefas longas durante o carregamento da página, para que ela permaneça rápida.
Otimizar callbacks de eventos
O atraso de entrada é apenas a primeira parte do que a INP mede. Você também precisa garantir que os callbacks de evento executados em resposta a uma interação do usuário sejam concluídos o mais rápido possível.
Ceder à linha de execução principal com frequência
O melhor conselho geral para otimizar callbacks de eventos é fazer o mínimo de trabalho possível neles. No entanto, a lógica de interação pode ser complexa, e talvez você só consiga reduzir um pouco o trabalho que elas fazem.
Se esse for o caso do seu site, tente dividir o trabalho em callbacks de eventos em tarefas separadas. Isso evita que o trabalho coletivo se torne uma tarefa longa que bloqueia a linha de execução principal, o que permite que outras interações que, de outra forma, estariam esperando na linha de execução principal sejam executadas mais cedo.
setTimeout é uma maneira de dividir tarefas, porque o callback transmitido a ele é executado em uma nova tarefa. É possível usar setTimeout por conta própria ou abstrair o uso em uma função separada para uma produção mais ergonômica.
Ainda que seja melhor ceder indiscriminadamente do que não ceder, há uma maneira mais sutil de fazer isso na linha de execução principal, que envolve ceder imediatamente após um callback de evento que atualiza a interface do usuário para que a lógica de renderização possa ser executada mais rapidamente.
Ceder para permitir que o trabalho de renderização ocorra mais cedo
Uma técnica de suspensão mais avançada envolve estruturar o código nos callbacks de eventos para limitar o que é executado apenas à lógica necessária para aplicar atualizações visuais ao próximo frame. Todo o resto pode ser adiado para uma tarefa posterior. Isso não apenas mantém os callbacks leves e ágeis, mas também melhora o tempo de renderização das interações, impedindo que as atualizações visuais bloqueiem o código de callback de eventos.
Por exemplo, imagine um editor de texto rich text que formata o texto enquanto você digita, mas também atualiza outros aspectos da interface em resposta ao que você escreveu, como contagem de palavras, destaque de erros de ortografia e outros feedbacks visuais importantes. Além disso, o aplicativo também pode precisar salvar o que você escreveu para que, se você sair e voltar, não perca nada.
Neste exemplo, as quatro coisas a seguir precisam acontecer em resposta aos caracteres digitados pelo usuário. No entanto, apenas o primeiro item precisa ser feito antes que o próximo frame seja apresentado.
- Atualize a caixa de texto com o que o usuário digitou e aplique a formatação necessária.
- Atualize a parte da interface que mostra a contagem de palavras atual.
- Executar a lógica para verificar se há erros de ortografia.
- Salvar as mudanças mais recentes (localmente ou em um banco de dados remoto).
O código para fazer isso pode ser semelhante ao seguinte:
textBox.addEventListener('input', (inputEvent) => {
// Update the UI immediately, so the changes the user made
// are visible as soon as the next frame is presented.
updateTextBox(inputEvent);
// Use `setTimeout` to defer all other work until at least the next
// frame by queuing a task in a `requestAnimationFrame()` callback.
requestAnimationFrame(() => {
setTimeout(() => {
const text = textBox.textContent;
updateWordCount(text);
checkSpelling(text);
saveChanges(text);
}, 0);
});
});
A visualização a seguir mostra como adiar as atualizações não críticas até depois do próximo frame pode reduzir a duração do processamento e, portanto, a latência geral da interação.
Embora o uso de setTimeout() dentro de uma chamada requestAnimationFrame() no exemplo de código anterior seja um pouco esotérico, é um método eficaz que funciona em todos os navegadores para evitar que o código não crítico bloqueie o próximo frame.
Evitar a sobrecarga de layout
A sobrecarga de layout, às vezes chamada de layout síncrono forçado, é um problema de desempenho de renderização em que o layout ocorre de forma síncrona. Isso ocorre quando você atualiza estilos em JavaScript e os lê na mesma tarefa. Há muitas propriedades em JavaScript que podem causar thrashing de layout.
O layout thrashing é um gargalo de desempenho porque, ao atualizar estilos e solicitar imediatamente os valores desses estilos em JavaScript, o navegador é forçado a realizar um trabalho de layout síncrono que, de outra forma, poderia ter esperado para ser executado de forma assíncrona mais tarde, depois que os callbacks de eventos terminassem de ser executados.
Minimizar o atraso na apresentação
O atraso de apresentação de uma interação vai do momento em que os callbacks de evento de uma interação terminam de ser executados até o ponto em que o navegador consegue renderizar o próximo frame que mostra as mudanças visuais resultantes.
Minimizar o tamanho do DOM
Quando o DOM de uma página é pequeno, o trabalho de renderização geralmente é concluído rapidamente. No entanto, quando os DOMs ficam muito grandes, o trabalho de renderização tende a aumentar com o tamanho do DOM. A relação entre o trabalho de renderização e o tamanho do DOM não é linear, mas DOMs grandes exigem mais trabalho para renderizar do que DOMs pequenos. Um DOM grande é problemático em dois casos:
- Durante a renderização inicial da página, em que um DOM grande exige muito trabalho para renderizar o estado inicial da página.
- Em resposta a uma interação do usuário, em que um DOM grande pode tornar as atualizações de renderização muito caras e, portanto, aumentar o tempo que o navegador leva para apresentar o próximo frame.
Lembre-se de que há casos em que DOMs grandes não podem ser reduzidos significativamente. Embora existam abordagens que você pode adotar para reduzir o tamanho do DOM, como nivelar o DOM ou adicionar ao DOM durante as interações do usuário para manter o tamanho inicial do DOM pequeno, essas técnicas podem não ser suficientes.
Use content-visibility para renderizar elementos fora da tela de forma lenta.
Uma maneira de limitar a quantidade de trabalho de renderização durante o carregamento de página e em resposta às interações do usuário é usar a propriedade CSS content-visibility, que renderiza elementos de forma lenta conforme eles se aproximam da janela de visualização. Embora o content-visibility possa exigir alguma prática para ser usado de forma eficaz, vale a pena investigar se o resultado é um tempo de renderização menor que pode melhorar a INP da página.
Esteja ciente dos custos de desempenho ao renderizar HTML usando JavaScript
Onde há HTML, há análise de HTML. Depois que o navegador termina de analisar o HTML em um DOM, ele precisa aplicar estilos, realizar cálculos de layout e, em seguida, renderizar esse layout. Esse é um custo inevitável, mas como você renderiza o HTML é importante.
Quando o servidor envia HTML, ele chega ao navegador como um stream. Streaming significa que a resposta HTML do servidor está chegando em partes. O navegador otimiza a forma como lida com um stream analisando de forma incremental os blocos desse stream à medida que eles chegam e renderizando-os aos poucos. Essa é uma otimização de desempenho, já que o navegador gera de forma implícita, periódica e automática durante o carregamento de página, e você recebe isso sem custo financeiro.
Embora a primeira visita a qualquer site sempre envolva alguma quantidade de HTML, uma abordagem comum começa com um pouco de HTML inicial e, em seguida, o JavaScript é usado para preencher a área de conteúdo. As atualizações subsequentes nessa área de conteúdo também ocorrem como resultado das interações do usuário. Isso geralmente é chamado de modelo de aplicativo de página única (SPA). Uma desvantagem desse padrão é que, ao renderizar HTML com JavaScript no cliente, você não só tem o custo do processamento do JavaScript para criar esse HTML, mas também o navegador não vai produzir até que tenha terminado de analisar e renderizar esse HTML.
No entanto, é importante lembrar que até mesmo sites que não são SPAs provavelmente envolvem alguma renderização de HTML por JavaScript como resultado de interações. Isso geralmente é aceitável, desde que você não renderize grandes quantidades de HTML no cliente, o que pode atrasar a apresentação do próximo frame. No entanto, é importante entender as implicações de desempenho dessa abordagem para renderizar HTML no navegador e como ela pode afetar a responsividade do site à entrada do usuário se você estiver renderizando muito HTML usando JavaScript.
Conclusão
Melhorar a INP do seu site é um processo iterativo. Quando você corrige uma interação lenta no campo, é provável que, especialmente se o site oferecer muita interatividade, você comece a encontrar outras interações lentas e precise otimizá-las também.
A chave para melhorar a INP é a persistência. Com o tempo, você pode melhorar a responsividade da página para que os usuários fiquem satisfeitos com a experiência que você está oferecendo. Também é provável que, ao desenvolver novos recursos para os usuários, você precise passar pelo mesmo processo para otimizar as interações específicas deles. Isso vai exigir tempo e esforço, mas vai valer a pena.