Em busca da correção do INP

Reduzir o TBT em 30 vezes e migrar para o Next.js ajudou o The Ecomonic Times a reduzir o INP quase quatro vezes, levando a uma redução de 50% na taxa de rejeição e um aumento de 43% nas visualizações de página.

Daya Ram Yadav
Daya Ram Yadav
Saurabh Rajpal
Saurabh Rajpal

Interação com a próxima exibição (INP, na sigla em inglês) é uma métrica que avalia a capacidade de resposta de um site à entrada do usuário. Uma boa capacidade de resposta significa que a página responde rapidamente às interações do usuário. Quanto menor for o INP de uma página, melhor será a resposta às interações do usuário.

Os valores de INP bons têm 200 milissegundos ou menos, os valores ruins são maiores do que 500 milissegundos e qualquer coisa intermediária precisa ser melhorada.

O começo impreciso

Quando o Google introduziu o INP como uma métrica experimental com potencial de evoluir para uma das Core Web Vitals, a equipe do Economic Times assumiu o desafio de corrigi-la antes de fazer a mudança, já que fornecer uma experiência do usuário de nível internacional é crucial para nossos principais valores comerciais.

O INP tem sido uma das métricas mais difíceis de resolver até agora. No início, não estava claro como medir o INP de maneira eficaz. O que dificultava ainda mais foi a falta de suporte da comunidade, inclusive a maioria dos provedores de monitoramento real de usuários (RUM, na sigla em inglês) que ainda não oferecia suporte a esse recurso. No entanto, tínhamos ferramentas RUM do Google, como o Chrome User Experience Report (CrUX), a biblioteca JavaScript web-vitals e outras que oferecem suporte a ele, que nos deram uma noção de onde estávamos enquanto avaliávamos o caminho à frente. Nosso INP estava perto de 1.000 milissegundos no nível da origem quando começamos.

Algo que surgiu ao corrigir o INP no campo foi que uma das métricas do laboratório a ser segmentada poderia ser o tempo total de bloqueio (TBT, na sigla em inglês). A TBT já foi bem documentada e apoiada pela comunidade. Apesar de já atingirmos os limites das Core Web Vitals, não estávamos indo tão bem em termos de TBT, já que eram mais de 3 segundos quando começamos.

O que é TBT e quais etapas seguimos para aprimorá-lo?

TBT é uma métrica de laboratório que mede a capacidade de resposta de uma página da Web à entrada do usuário durante o carregamento da página. Qualquer tarefa que leve mais de 50 milissegundos para ser executada é considerada uma tarefa longa, e o tempo após o limite de 50 milissegundos é conhecido como tempo de bloqueio.

O TBT é calculado pela soma do tempo de bloqueio de todas as tarefas longas durante o carregamento da página. Por exemplo, se houver duas tarefas longas durante o carregamento, o tempo de bloqueio será determinado da seguinte maneira:

  • A Tarefa A leva 80 milissegundos (30 milissegundos a mais que 50 milissegundos).
  • A tarefa B leva 100 milissegundos (50 milissegundos a mais que 50 milissegundos).

O TBT da página será: 80 milissegundos (30 + 50). Quanto menor o TBT, melhor. Além disso, o TBT também correlaciona bem com o INP.

Confira uma comparação em laboratório do nosso TBT antes e depois de aprimorá-lo:

Uma imagem composta de tarefas longas durante a inicialização, como mostrado no painel de desempenho do Chrome DevTools, e um relatório de métricas da página. A linha de execução principal é bloqueada durante o carregamento da página por 3.260 milissegundos.
A linha de execução principal durante a inicialização antes de otimizar o TBT. O TBT é de 3.260 milissegundos.
Uma imagem composta de tarefas longas durante a inicialização, como mostrado no painel de desempenho do Chrome DevTools, e um relatório de métricas da página. A linha de execução principal é bloqueada durante o carregamento da página por 120 milissegundos.
A linha de execução principal durante a inicialização após a otimização do TBT. O TBT é de 120 milissegundos.

Minimizar o trabalho da linha de execução principal

A linha de execução principal do navegador lida com tudo, desde a análise de HTML e criação do DOM até a análise de CSS e a aplicação de estilos, além da avaliação e execução do JavaScript. A linha de execução principal também processa interações do usuário, ou seja, clicar, tocar e pressionar. Se a linha de execução principal estiver ocupada fazendo outro trabalho, ela pode não responder às entradas do usuário de forma eficiente e gerar uma experiência instável do usuário.

Essa foi a tarefa mais difícil para nós, já que temos nossos próprios algoritmos para detectar a identidade do usuário para veicular anúncios com base no status da assinatura e scripts de terceiros para testes A/B, análises e muito mais.

No início, tomamos pequenas medidas, como remover a prioridade do carregamento de ativos de negócios menos importantes. Em segundo lugar, usamos requestIdleCallback para trabalhos não essenciais, o que pode ajudar a reduzir o TBT.

if ('requestIdleCallback' in window) {
  this.requestIdleCallbackId = requestIdleCallback(fetchMarketsData.bind(this), {timeout: 3000});
} else {
  fetchMarketsData(); // Fallback in case requestIdleCallback is not supported
}

É recomendável especificar um tempo limite ao usar o requestIdleCallback, porque ele garante que, se o tempo determinado já tiver passado e o callback ainda não tiver sido chamado, ele vai ser executado imediatamente após o tempo limite.

Minimizar o tempo de avaliação do script

Também fazemos o carregamento lento de bibliotecas de terceiros usando componentes carregáveis. Também removemos JavaScript e CSS não utilizados criando o perfil da página com a ferramenta de cobertura no Chrome DevTools. Isso nos ajudou a identificar áreas em que o tree shaking era necessário para enviar menos código durante o carregamento da página e, portanto, reduzir o tamanho inicial do pacote do aplicativo.

Uma captura de tela da ferramenta de cobertura no Chrome DevTools. Aqui, a ferramenta exibe partes não utilizadas de arquivos JavaScript e CSS durante o carregamento da página.

Reduzir o tamanho do DOM

De acordo com o Lighthouse, tamanhos de DOM grandes aumentam o uso de memória, causam recálculos de estilo mais longos e produzem reflows de layout caros.

Captura de tela da auditoria de tamanho do DOM no Lighthouse. O número de elementos DOM relatados é de 2.706 elementos.

Reduzimos o número de nós DOM de duas maneiras:

  • Primeiro, renderizamos os itens do menu de acordo com a solicitação do usuário (ao clicar). Isso reduziu o tamanho do DOM em cerca de 1.200 nós.
  • Segundo, fizemos o carregamento lento de widgets menos importantes.

Devido a todos esses esforços, reduzimos o TBT significativamente e nosso INP foi reduzido em quase 50%:

Uma captura de tela da auditoria do INP no CrUX. O INP da página é de 539 milissegundos, o que excede o limite de "insatisfatório".

Nesse ponto, quase ficamos sem ganhos fáceis para reduzir ainda mais o TBT (e o INP por proxy), mas sabíamos que tínhamos muito espaço para melhorias. Foi quando decidimos atualizar nosso boilerplate de interface personalizado para a versão mais recente do React com o Next.js para usar melhor os hooks e evitar uma nova renderização desnecessária de componentes.

Devido a atualizações mais frequentes e a um tráfego comparativamente menor em comparação com outras partes do site, começamos a migrar nossas páginas de tópicos para o Next.js. Também usamos a PartyTown para descarregar outro trabalho pesado da linha de execução principal para workers da Web, além de técnicas como requestIdleCallBack para adiar tarefas não críticas.

Como melhorar o INP ajudou o The Economic Times?

TBT e INP atual na origem

No momento em que publicamos esta postagem, o TBT da nossa origem era de 120 milissegundos, contra 3.260 milissegundos,quando começamos nossos esforços de otimização. Da mesma forma, a INP da nossa origem foi de 257 milissegundos após nossas iniciativas de otimização, uma queda de mais de 1.000 milissegundos.

Uma captura de tela da auditoria do INP no CrUX. O INP da página é de 257 milissegundos e está dentro dos limites de "precisa de melhorias".

Tendência do CrUX do INP

O tráfego recebido nas páginas de tópicos representa uma parte significativamente menor do tráfego geral. Por isso, era um local ideal para experimentação. Os resultados do CrUX e os resultados comerciais foram muito encorajadores e nos levaram a expandir nossos esforços em todo o site para colher mais benefícios.

Captura de tela das distribuições de INP visualizadas no CrUX por um período de quatro meses, entre julho de 2022 e outubro de 2022. Os valores nos limites "ruim" e "precisa de melhorias" diminuíram um pouco, enquanto os valores dentro do limite "bom" aumentaram.

Análise TBT do Akamai mPulse

Usamos o Akamai mPulse (link em inglês) como nossa solução RUM, que mede o TBT em campo. Observamos uma redução consistente no TBT, correspondendo claramente aos resultados dos nossos esforços para reduzir a INP. Como pode ser visto na captura de tela abaixo, os valores de TBT acabaram caindo de aproximadamente 5 segundos para cerca de 200 milissegundos no campo.

Captura de tela de um gráfico no Akamai mPulse, mostrando um declínio no TBT ao longo de aproximadamente um mês.

Resultado comercial

No geral, nossos esforços para reduzir o TBT em 30 vezes, além da migração para o Next.js, nos ajudaram a reduzir o INP em quase quatro vezes, o que levou a uma redução de 50% na taxa de rejeição e de 43% nas visualizações de página nas páginas de tópicos.

Captura de tela do Google Analytics comparando visualizações de página com taxa de rejeição. Devido às otimizações feitas para o INP no site do The Economic Times, houve uma redução de 50% na taxa de rejeição e um aumento de 43% nas visualizações de página.

Conclusão

Para resumir, a INP ajudou amplamente a determinar problemas de desempenho de tempo de execução em partes do site do Economic Times. Ela provou ser uma das métricas mais eficazes para impactar positivamente os resultados dos negócios. Em razão dos números encorajadores que observamos como resultado desse esforço, estamos motivados a ampliar nossos esforços de otimização para outras áreas de nosso site e colher mais benefícios.