Como a Trendyol reduziu o INP em 50%, resultando em um aumento de 1% na taxa de cliques

Este estudo de caso descreve um fluxo de trabalho detalhado de depuração e melhoria de INP no React usado pelo Trendyol aproveitando ferramentas do Google, como PageSpeed Insights (PSI), Chrome DevTools e a API scheduler.yield.

Dois componentes essenciais de qualquer site de e-commerce são a página de informações do produto (PLP, na sigla em inglês) e a página de detalhes do produto (PDP, na sigla em inglês). O tráfego de e-commerce geralmente vem das páginas de informações do produto, seja por campanhas de e-mail, mídias sociais ou anúncios. Como resultado, é fundamental garantir que a experiência de PLP seja projetada com cuidado para reduzir o tempo necessário para fazer uma compra. Priorizar a qualidade da experiência do usuário é essencial para alcançar o sucesso. Publicações de pesquisa como Milliseconds Make Millions (em inglês) já revelaram o impacto significativo do desempenho na Web sobre a disposição dos consumidores de gastar dinheiro e se engajar com marcas on-line.

A Trendyol é uma plataforma de comércio eletrônico com cerca de 30 milhões de clientes e 240 mil vendedores,que nos levou a nos tornar a primeira empresa na Turquia, com valor de mais de US $10 bilhões, e uma das principais plataformas de comércio eletrônico do mundo.

Para atingir o objetivo de fornecer a melhor experiência do usuário possível em escala, mantendo a flexibilidade do conteúdo e trabalhando com uma versão mais antiga do React, a Trendyol se concentrou na Interaction to Next Paint (INP) como uma métrica importante para melhorar. Este estudo de caso descreve a jornada da Trendyol de melhorar o INP no PLP, resultando em uma redução de 50% do INP e um aumento de 1% na métrica de negócios de resultado da pesquisa.

Processo de investigação do INP da Trendyol

O INP mede a capacidade de resposta de um site à entrada do usuário. Um bom INP indica que o navegador é capaz de responder de maneira rápida e confiável a todas as entradas do usuário e pintar a página novamente, o que é um componente essencial de uma boa experiência do usuário.

A jornada da Trendyol para melhorar o INP no PLP começou com uma análise completa da experiência do usuário antes de qualquer melhoria ser feita. Com base em um relatório da PSI, a experiência real do usuário no PLP teve um INP de 963 milissegundos em dispositivos móveis, conforme mostrado na figura a seguir.

INP da Trendyol de acordo com a leitura do CrUX no PageSpeed Insights. O INP da Trendyol, em 5 de setembro de 2023, era de 963 milissegundos, o que está no intervalo "ruim".
INP da Trendyol em 5 de setembro de 2023 pelo PSI.

Para garantir uma boa capacidade de resposta, os proprietários de sites precisam buscar um INP abaixo ou em 200 milissegundos, o que significa que, naquele momento, o INP da Trendyol estava no intervalo "ruim".

Felizmente, o PSI fornece dados de campo para páginas incluídas no Chrome User Experience Report (CrUX, na sigla em inglês) e dados detalhados de diagnóstico de laboratório. Analisando os dados do laboratório, a auditoria do tempo de execução do JavaScript do Lighthouse sugeriu que o script search-result-v2 estava ocupando a linha de execução principal por mais tempo do que outros scripts na página.

Uma leitura de fontes de tarefas longas no Lighthouse para o site da Trendyol. Uma das principais fontes de tarefas longas é um script que lida com os resultados de pesquisa no PLP da Trendyol.
Auditoria de tempo de execução do JavaScript da Trendyol no Lighthouse em 5 de setembro de 2023 pela PSI.

Para identificar gargalos reais, usamos o painel de desempenho no Chrome DevTools para resolver problemas na experiência do PLP e identificar a origem do problema. A emulação do desempenho de dispositivos móveis com uma lentidão de CPU de 4X no Chrome DevTools revelou uma tarefa de 700 a 900 milissegundos de duração na linha de execução principal. Se a linha de execução principal estiver ocupada com outras tarefas por mais de 50 milissegundos, talvez ela não consiga responder à entrada do usuário em tempo hábil, o que resulta em uma experiência insatisfatória.

Captura de tela de uma sessão de caracterização de perfil de desempenho no Chrome DevTools para o PLP da Trendyol. A tarefa longa retratada é executada por 737, 6 milissegundos e faz parte de um callback do Intersection Observer.
Um criador de perfil de desempenho de tarefas longas no PLP da Trendyol no painel de desempenho do Chrome DevTools.

A tarefa mais longa foi causada por um callback da API Intersection Observer no script de resultados da pesquisa em um componente do React. Nesse ponto, começamos a tentar dividir essa tarefa longa em pequenos fragmentos para dar ao navegador mais oportunidades de responder a trabalhos de maior prioridade, incluindo interações do usuário.

Acontece que o uso da operação setState, que aciona a rerenderização do React dentro do callback do Intersection Observer, tem um custo alto, o que pode ser problemático para dispositivos mais simples, ocupando a linha de execução principal por muito tempo.

Um método usado pelos desenvolvedores para dividir tarefas em tarefas menores envolve setTimeout. Usamos essa técnica para adiar a execução da chamada setState em uma tarefa separada. Embora a setTimeout permita adiar a execução de JavaScript, ela não fornece controle sobre a prioridade. Isso nos levou a participar do teste de origem scheduler.yield para garantir a continuação da execução do script após o fim da linha de execução principal:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

A adição desse método de rendimento ao código de PLP resultou em um INP aprimorado, já que a tarefa longa principal foi dividida em uma série de tarefas menores, o que permite que trabalhos de maior prioridade, como interações do usuário e trabalhos de renderização subsequentes, aconteçam mais cedo do que teriam.

Captura de tela de uma sessão de caracterização de perfil de desempenho no Chrome DevTools para o PLP da Trendyol. A tarefa longa que antes era executada por 737,6 milissegundos agora está dividida em várias tarefas menores.
Tarefa dividida em tarefas menores.

A Trendyol usa o framework do PuzzleJs para implementar uma arquitetura de micro-front-end usando o React v16.9.0. Com o React 18, o mesmo desempenho pode ser alcançado, mas, por vários motivos, a Trendyol não pode fazer upgrade no momento.

Resultados comerciais

Para medir o impacto da melhoria de INP implementada, executamos um teste A/B para ver como as métricas de negócios foram afetadas. No geral, nossas mudanças na PLP resultaram em uma melhoria significativa, incluindo uma redução de 50% no INP e um aumento de 1% nas taxas de cliques da página de informações do produto para a página de detalhes do produto por sessão do usuário. Na figura a seguir, é possível ver como o INP melhorou o PLP ao longo do tempo:

Uma captura de tela do INP de 75o percentil da Trendyol ao longo de seis meses. Ao final dos seis meses, o INP da Trendyol diminuiu para quase 650 milissegundos,de quase 1.400 milissegundos.
Melhorias na INP no 75o percentil ao longo do tempo.

Conclusão

A otimização de INP é um processo complexo e iterativo, mas pode ser facilitado com um fluxo de trabalho claro. Uma abordagem simples para depurar e melhorar o INP do site depende se você está coletando seus próprios dados de campo. Caso contrário, o PSI e o Lighthouse são um bom ponto de partida. Depois de identificar as páginas com problemas, use o DevTools para se aprofundar e tentar reproduzir problemas.

Se você ceder à linha de execução principal de vez em quando para dar ao navegador mais oportunidades de fazer trabalhos urgentes, seu site ficará mais responsivo, garantindo que seus clientes tenham uma melhor experiência do usuário. APIs de agendamento mais recentes, como scheduler.yield(), facilitam essa tarefa.

Um agradecimento especial a Jeremy Wagner, Barry Pollard e Houssein Djirdeh, do Google, e à equipe de engenharia da Trendyol pela contribuição para esse trabalho.