Diagnosticar manualmente as interações lentas no laboratório

Aprender a usar seus dados de campo no laboratório para reproduzir e identificar as causas por trás das interações lentas por meio de testes manuais.

Uma parte desafiadora da otimização da Interaction to Next Paint (INP) é descobrir o que está causando uma INP ruim. Há uma grande variedade de possíveis causas: scripts de terceiros que agendam muitas tarefas na linha de execução principal, tamanhos grandes de DOM, callbacks de eventos caros, entre outros.

Encontrar maneiras de corrigir uma INP ruim pode ser difícil. Para começar, você precisa saber quais interações tendem a ser responsáveis pelo INP de uma página. Se você não souber quais interações no seu site tendem a ser as mais lentas do ponto de vista do usuário real, primeiro leia Encontrar interações lentas no campo. Depois de ter dados de campo para guiá-lo, é possível testar essas interações específicas manualmente nas ferramentas de laboratório para descobrir por que essas interações são lentas.

E se você não tiver dados de campo?

Ter dados de campo é vital, porque economiza muito tempo tentando descobrir quais interações precisam ser otimizadas. No entanto, você pode estar em uma posição em que não tem dados de campo. Se isso descreve sua situação, ainda é possível encontrar interações para melhorar, embora isso exija um pouco mais de esforço e uma abordagem diferente.

O tempo total de bloqueio (TBT, na sigla em inglês) é uma métrica de laboratório que avalia a capacidade de resposta da página durante o carregamento e tem uma boa correlação com o INP. Se a página tiver um TBT alto, isso é um sinal importante de que talvez ela não seja muito responsiva às interações do usuário durante o carregamento inicial da página.

Para descobrir o TBT da sua página, use o Lighthouse ou o PageSpeed Insights. Se o TBT de uma página não atingir o limite "bom", é provável que a linha de execução principal esteja muito ocupada durante o carregamento da página, e isso pode afetar a rapidez com que as interações ocorrem durante esse momento crucial no ciclo de vida da página.

Para encontrar interações lentas após o carregamento da página, talvez seja necessário usar outros tipos de dados, como fluxos de usuários comuns que você já identificou na análise do seu site. Se você trabalha em um site de e-commerce, por exemplo, um fluxo de usuário comum seria as ações que os usuários realizam ao adicionar itens a um carrinho de compras on-line e, posteriormente, passar pelo processo de finalização da compra.

Independentemente de você ter ou não dados de campo, a próxima etapa é testar manualmente e reproduzir interações lentas, porque só quando você pode identificar de forma conclusiva uma interação lenta é possível corrigi-la.

Reproduzir interações lentas no laboratório

Existem várias maneiras de reproduzir interações lentas no laboratório por meio de testes manuais. Confira abaixo um framework que pode ser usado para reproduzir interações lentas em um ambiente de laboratório, minimizando o esforço cognitivo.

Não entrar em contato com o criador de perfil de desempenho imediatamente

Se você já conhece o criador de perfil de desempenho do Chrome, sabe que ele fornece toneladas de informações de diagnóstico úteis para solucionar problemas de desempenho da página. É uma ferramenta útil e tem muitas vantagens.

No entanto, a desvantagem é que o criador de perfil de desempenho do Chrome não oferece uma visualização ao vivo durante a interação com a página. O uso dele leva muito tempo, e há maneiras mais eficientes de testar as interações manualmente primeiro. A ideia é gastar o mínimo de tempo e esforço para reproduzir interações lentas e, após uma interação lenta ser identificada de forma conclusiva, use o Performance Profiler para se aprofundar nas causas por trás dela.

Usar a extensão do Chrome "Métricas da Web"

A Extensão do Chrome Métricas da Web envolve o menor esforço para testar manualmente a latência de interação. Depois de instalada, a extensão exibe dados de interação no console do DevTools, desde que você faça o seguinte primeiro:

  1. No Chrome, clique no ícone de extensões à direita da barra de endereço.
  2. Localize a extensão Web Vitals no menu suspenso.
  3. Clique no ícone à direita para abrir as configurações da extensão.
  4. Clique em Opções.
  5. Ative a caixa de seleção Registro do console na tela resultante e clique em Salvar.

Depois, abra o console no Chrome DevTools e comece a testar interações suspeitas no seu site. À medida que você interage com a página, dados de diagnóstico úteis são exibidos no console.

Uma captura de tela dos registros do console que a extensão Métricas da Web oferece para interações. O registro contém detalhes como horários e outras informações contextuais.
Uma entrada de console da extensão de Métricas da Web quando a geração de registros do console estiver ativada. Cada interação qualificada registrará os dados de interação no console.

Usar um snippet de JavaScript

Por mais útil que possa ser, a extensão Web Vitals pode não ser uma opção viável para todos. As extensões do navegador podem ser bloqueadas em alguns ambientes devido às políticas de segurança do dispositivo. As extensões também não podem ser instaladas em dispositivos móveis. Esse último é problemático se você quiser testar manualmente em um dispositivo físico Android com depuração remota.

Um método alternativo ao uso da extensão Web Vital envolve copiar e colar um pouco de JavaScript no console do DevTools. O código a seguir oferece a mesma saída do console que a extensão Métricas da Web para cada interação:

let worstInp = 0;

const observer = new PerformanceObserver((list, obs, options) => {
  for (let entry of list.getEntries()) {
    if (!entry.interactionId) continue;

    entry.renderTime = entry.startTime + entry.duration;
    worstInp = Math.max(entry.duration, worstInp);

    console.log('[Interaction]', entry.duration, `type: ${entry.name} interactionCount: ${performance.interactionCount}, worstInp: ${worstInp}`, entry, options);
  }
});

observer.observe({
  type: 'event',
  durationThreshold: 0, // 16 minimum by spec
  buffered: true
});

Depois de determinar que uma interação é confiável, é possível criar um perfil para ela no Criador de perfil de desempenho para receber informações detalhadas sobre por que ela está lenta.

E se você não conseguir reproduzir uma interação lenta?

E se os dados de campo sugerirem que uma interação específica é lenta, mas você não puder reproduzir manualmente o problema do laboratório? Há alguns motivos para isso, e é um desafio comum na solução de problemas de desempenho de qualquer tipo.

Pelo menos uma vez, as circunstâncias enquanto você testa as interações dependem do hardware e da conexão de rede que você está usando. Afinal, você pode estar usando um dispositivo rápido em uma conexão rápida, mas isso não significa que seus usuários têm tanta sorte. Se essa situação se aplicar ao seu caso, é possível:

  1. Se você tiver um dispositivo físico Android, use a depuração remota (link em inglês) para abrir uma instância do Chrome DevTools na máquina host e tente reproduzir interações lentas lá. Dispositivos móveis geralmente não são tão rápidos quanto laptops ou computadores. Portanto, interações lentas podem ser observadas mais prontamente nessas condições.
  2. Se você não tiver um dispositivo físico, ative o recurso de limitação de CPU no Chrome DevTools.
  3. Tente as etapas 1 e 2 juntas, já que também é possível ativar a limitação de CPU na instância do DevTools para um dispositivo físico Android.

Outra causa pode ser que você está esperando uma página ser carregada antes de interagir com ela, mas seus usuários não são. Se você estiver em uma rede rápida, simule condições de rede mais lentas ativando a limitação de rede e depois interagir com a página assim que ela for exibida. Faça isso porque a linha de execução principal geralmente fica mais ocupada durante a inicialização, e os testes nesse momento podem revelar o que os usuários estão enfrentando.

Gravar um rastro

Para saber mais sobre por que uma interação está lenta, a próxima etapa é usar o Performance Profiler no Chrome DevTools. Para criar o perfil de uma interação no Criador de perfil de desempenho do Chrome, faça o seguinte:

  1. Abra a página que você precisa testar.
  2. Abra o Chrome DevTools e acesse o painel Desempenho.
  3. Clique no botão Gravar no canto superior esquerdo do painel para iniciar o rastreamento.
  4. Faça as interações que você quer criar para o perfil.
  5. Clique novamente no botão Gravar para interromper o rastreamento.

Quando o criador de perfil é preenchido, o primeiro local a ser verificado é o resumo da atividade na parte de cima dele. O resumo da atividade mostra barras vermelhas na parte superior onde tarefas longas ocorreram na gravação. Isso permite que você amplie rapidamente as áreas problemáticas.

Uma captura de tela do resumo da atividade no painel de desempenho do Chrome DevTools. A atividade exibida é principalmente de JavaScript, o que resulta em uma tarefa longa, que está destacada em vermelho acima do Flame Chart.
O resumo da atividade na parte de cima do Performance Profiler do Chrome. As tarefas longas são destacadas em vermelho acima do Flame Chart da atividade. Nesse caso, o trabalho significativo de script foi responsável pela maior parte do trabalho na tarefa longa.

Você pode se concentrar rapidamente nas áreas problemáticas arrastando e selecionando uma região no resumo de atividades. Depois de se concentrar no local em que a interação ocorreu, a faixa Interações ajuda a alinhar a interação e a atividade que ocorreu na faixa da linha de execução principal abaixo dela:

Uma captura de tela de uma interação visualizada no painel de desempenho do Chrome DevTools. Uma faixa de interações acima da faixa da linha de execução principal mostra a duração de uma interação, que pode ser alinhada com a atividade da linha de execução principal.
Uma interação criada pelo criador de perfil de desempenho no DevTools do Chrome. A faixa Interações mostra uma série de eventos que correspondem a uma interação de clique. As entradas de rastreamento de interações abrangem as tarefas responsáveis por conduzir a interação.

A partir daqui, é uma questão de se aprofundar no problema que causa a interação lenta. Há muitos fatores que podem contribuir para a alta latência de interação. Alguns deles são abordados mais adiante neste guia.

Usar os períodos do Lighthouse como alternativa ao rastreamento

O criador de perfil de desempenho do Chrome, ainda que rico em informações de diagnóstico, pode ser um pouco intimidante para quem não é iniciado. Uma alternativa ao criador de perfil de desempenho é o modo de período do Lighthouse. Para usar esse modo, faça o seguinte:

  1. Com o DevTools aberto, acesse a guia Lighthouse.
  2. Na seção Modo, selecione a opção Período.
  3. Selecione o tipo de dispositivo Computador ou Dispositivo móvel na seção Dispositivo.
  4. Verifique se pelo menos a caixa de seleção Desempenho está marcada no rótulo Categorias.
  5. Clique no botão Iniciar período.
  6. Teste as interações na página sobre a qual você quer coletar dados.
  7. Clique no botão Período de término e aguarde a auditoria ser exibida.
  8. Depois que a auditoria for preenchida na guia do Lighthouse, você poderá filtrar as auditorias por INP clicando no link INP ao lado do rótulo Mostrar auditorias relevantes para.

Uma lista suspensa de auditorias reprovadas ou aprovadas será exibida. Ao expandir essa lista suspensa, é necessário haver um detalhamento do tempo gasto durante a interação.

Captura de tela de uma auditoria do Lighthouse fornecida pelo modo de período. A auditoria é específica ao INP e mostra detalhes de uma interação, como uma captura de tela do elemento que a acionou e uma tabela abaixo detalhando onde o tempo foi gasto no processamento da interação.
Uma interação criada no modo de período do Lighthouse. Quando as interações são feitas com a página, o Lighthouse fornece uma auditoria que detalha onde o tempo durante uma interação foi gasto e o divide por atraso de entrada, atraso de processamento e atraso da apresentação.

Como identificar longos atrasos de entrada

Um fator que pode contribuir para a alta latência de interação é o atraso de entrada. O atraso de entrada é a primeira fase de uma interação. Esse é o período entre o recebimento da ação do usuário pelo sistema operacional pela primeira vez e o momento em que o navegador pode começar a processar o primeiro evento acionado por essa entrada. O atraso de entrada termina assim que os callbacks do evento da interação começam a ser executados.

A identificação de atrasos de entrada no Performance Profiler do Chrome pode ser feita localizando o início de uma interação na faixa de interações e descobrindo o início de quando os callbacks de eventos dessa interação começam a ser executados.

Uma quantidade de atraso de entrada sempre precisa ser esperada, já que o sistema operacional leva algum tempo para transmitir o evento de entrada ao navegador, mas você tem algum controle sobre a duração desse atraso. O importante é descobrir se há trabalho na linha de execução principal que esteja impedindo a execução dos callbacks.

Representação do atraso de entrada no painel de desempenho do Chrome. O início da interação ocorre significativamente antes dos callbacks de eventos devido ao aumento do atraso de entrada devido ao acionamento de um timer a partir de um script de terceiros.
Atraso na entrada causado por uma tarefa disparada por um timer de um script de terceiros.

Na figura anterior, uma tarefa de um script de terceiros está em execução enquanto o usuário tenta interagir com a página, o que estende o atraso de entrada. O atraso estendido de entrada afeta a latência da interação e, portanto, pode afetar o INP da página.

Como identificar callbacks de eventos caros

Os callbacks de eventos são executados imediatamente após o atraso de entrada. Se um callback de evento for executado por muito tempo, ele atrasa a apresentação do próximo frame pelo navegador e pode aumentar significativamente a latência total de uma interação. Callbacks de eventos de longa duração podem ser resultado de JavaScript próprio, caro ou de terceiros, e, em alguns casos, ambos.

Representação das tarefas de callback de eventos no painel de performance do Chrome. Os callbacks de eventos ocorrem em eventos apontadores e de clique, que ocorrem em uma tarefa longa.
Os callbacks de eventos executados em resposta a uma interação de clique, conforme mostrado no Performance Profiler no Chrome DevTools. Observe o triângulo vermelho no canto superior direito das entradas Event: pointerdown e Event: click, que identifica callbacks de eventos caros.

A descoberta de callbacks de eventos caros pode ser feita observando o seguinte em um rastreamento de interação específica:

  1. Determinar se a tarefa associada aos callbacks do evento é uma tarefa longa. Para revelar tarefas longas em uma configuração de laboratório de forma mais confiável, pode ser necessário ativar a limitação de CPU no painel de desempenho ou conectar um dispositivo Android de camada baixa a intermediária e usar a depuração remota.
  2. Se a tarefa que executa os callbacks de evento for longa, procure entradas de manipulador de eventos (por exemplo,entradas com nomes como Event: click) na pilha de chamadas que tenham um triângulo vermelho no canto superior direito da entrada. Esses são callbacks de eventos caros.

Para lidar com callbacks de eventos caros, tente uma das seguintes estratégias:

  1. Fazer o mínimo de trabalho possível. Tudo o que acontece em um callback de evento caro é estritamente necessário? Caso contrário, considere remover esse código completamente, se possível, ou adiar a execução para um momento posterior, se não puder. Também é possível aproveitar os recursos de framework para ajudar. Por exemplo, a classe PureComponent e o recurso de memorização do React podem pular o trabalho de renderização desnecessário quando as propriedades e o estado de um componente não mudaram.
  2. Adie o trabalho que não é de renderização no callback do evento para um momento posterior. Tarefas longas podem ser divididas gerando a linha de execução principal. Sempre que você resultar na linha de execução principal, estará finalizando a execução da tarefa atual e dividindo o restante do trabalho em uma tarefa separada. Isso dá ao renderizador a chance de processar atualizações na interface do usuário que foram realizadas anteriormente no callback do evento. Se você estiver usando o React, o recurso de transições pode fazer isso.

Ao empregar essas estratégias, você faz com que os callbacks de eventos fiquem em um lugar em que eles respondam mais rapidamente à entrada do usuário.

Como identificar atrasos na apresentação

Longos atrasos de entrada e callbacks de eventos caros não são os únicos possíveis culpados de uma INP ruim. Às vezes, as atualizações de renderização que ocorrem em resposta a até mesmo pequenas quantidades de código de callback do evento podem ser caras. O tempo que o navegador leva para renderizar atualizações visuais na interface do usuário para refletir o resultado de uma interação é conhecido como atraso da apresentação.

Trabalho de renderização visualizado no painel de desempenho do Chrome DevTools. O trabalho de renderização ocorre após o callback do evento para pintar o frame seguinte.
Tarefas de renderização conforme mostrado no Performance Profiler do Chrome. O trabalho de renderização é mostrado em roxo, com o trabalho de tinta em verde.

De todas as possíveis causas de alta latência de interação, o trabalho de renderização pode ser a mais difícil de solucionar e corrigir, mas o resultado vale o esforço. O excesso de trabalho de renderização pode ser causado por qualquer um dos seguintes motivos:

  • Tamanhos grandes do DOM. O trabalho de renderização necessário para atualizar a apresentação de uma página geralmente aumenta junto com o tamanho do DOM da página. Para mais informações, leia Como tamanhos grandes de DOM afetam a interatividade e o que você pode fazer a respeito.
  • Reflows forçados. Isso acontece quando você aplica mudanças de estilo a elementos em JavaScript e depois consulta os resultados desse trabalho. O resultado é que o navegador precisa realizar o trabalho de layout antes de fazer qualquer outra coisa, para que ele possa retornar os estilos atualizados. Para mais informações e dicas sobre como evitar reflows forçados, leia Evitar layouts grandes e complexos e a troca frequente de layouts.
  • Trabalho excessivo ou desnecessário em callbacks de requestAnimationFrame. Os callbacks requestAnimationFrame() são executados durante a fase de renderização do loop de eventos e precisam ser concluídos antes que o próximo frame possa ser apresentado. Se você estiver usando requestAnimationFrame() para fazer um trabalho que não envolva mudanças na interface do usuário, entenda que pode haver atraso no próximo frame.
  • Callbacks do ResizeObserver. Esses callbacks são executados antes da renderização e podem atrasar a apresentação do próximo frame se o trabalho neles for caro. Assim como nos callbacks de eventos, adie qualquer lógica que não seja necessária para o próximo frame.

A solução de problemas de INP é um processo iterativo

Descobrir o que está causando uma alta latência de interação que contribui para uma INP ruim exige muito trabalho. Mas, se você conseguir identificar as causas, já estará na metade do caminho. Ao seguir uma abordagem metódica para solucionar problemas de INP ruim, é possível fixar com segurança o que está causando um problema e chegar mais rapidamente à correção certa. Para revisar:

  • Confie nos dados de campo para encontrar interações lentas.
  • Teste manualmente as interações de campo problemáticas no laboratório para ver se elas são reprodutíveis.
  • Identifique se a causa é um longo atraso de entrada, callbacks de evento caros ou trabalhos de renderização caros.
  • Esse processo precisa ser repetido.

O último deles é o mais importante. Como a maioria dos outros trabalhos que você faz para melhorar o desempenho da página, a solução de problemas e o aprimoramento de INP é um processo cíclico. Quando você corrigir uma interação lenta, passe para a próxima e repita até começar a ver resultados. Fique atento.