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.
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.
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:
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.
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.
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%:
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.
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.
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.
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.
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.