Cómo Trendyol redujo el INP en un 50%, lo que generó un aumento del 1% en la tasa de clics

En este caso de éxito, se describe un flujo de trabajo paso a paso para depurar y mejorar INP en React que usa Trendyol. Para ello, aprovecha las herramientas de Google, como PageSpeed Insights (PSI), Herramientas para desarrolladores de Chrome y la API de scheduler.yield.

Dos componentes fundamentales de cualquier sitio web de comercio electrónico son la página de ficha de producto (PLP) y la página de detalles del producto (PDP). El tráfico de comercio electrónico suele provenir de las páginas de fichas de productos, ya sea a través de campañas por correo electrónico, redes sociales o anuncios. Por lo tanto, es fundamental asegurarse de que la experiencia de PLP esté cuidadosamente diseñada para reducir el tiempo que lleva realizar una compra. Priorizar la calidad de la experiencia del usuario es esencial para lograr el éxito. Algunas publicaciones de investigación, como Milliseconds Make Millions, ya revelaron el impacto significativo del rendimiento web en la disposición de los consumidores para invertir dinero y comprometerse con las marcas en línea.

Trendyol es una plataforma de comercio electrónico con alrededor de 30 millones de clientes y 240,000 vendedores, lo que nos llevó a convertirnos en la primera empresa de Türkiye con una valoración de más de USD 10, 000 millones y en una de las principales plataformas de comercio electrónico del mundo.

Para lograr su objetivo de proporcionar la mejor experiencia del usuario posible a gran escala, mantener la flexibilidad del contenido y trabajar con una versión anterior de React, Trendyol se enfocó en Interaction to Next Paint (INP) como métrica clave para mejorar. En este caso de éxito, se describe el recorrido de Trendyol para mejorar el INP en su PLN, lo que dio como resultado una reducción del 50% del INP y un aumento del 1% en la métrica comercial de los resultados de la búsqueda.

Proceso de investigación de INP de Trendyol

INP mide la capacidad de respuesta de un sitio web a las entradas del usuario. Un buen INP indica que el navegador puede responder de manera rápida y confiable a todas las entradas del usuario y volver a pintar la página, lo que es un componente clave de una buena experiencia del usuario.

El recorrido de Trendyol para mejorar INP en su PLP comenzó con un análisis exhaustivo de la experiencia del usuario antes de implementar mejoras. Según un informe de PSI, la experiencia real del usuario del PLP tuvo un INP de 963 milisegundos en dispositivos móviles, como se muestra en la siguiente figura.

Es el INP de Trendyol según la lectura de CrUX en PageSpeed Insights. Al 5 de septiembre de 2023, el INP de Trendyol era 963 milisegundos, que se encuentra en el rango "deficiente".
INP de Trendyol al 5 de septiembre de 2023 de PSI.

Para garantizar una buena capacidad de respuesta, los propietarios del sitio deben tener como objetivo un INP inferior o a 200 milisegundos. Esto significa que, en ese momento, el INP de Trendyol estaba en el rango "deficiente".

Afortunadamente, PSI proporciona datos de campo para las páginas incluidas en el Informe de experiencia del usuario de Chrome (CrUX), así como datos de diagnóstico de laboratorio detallados. Al ver los datos del lab, la auditoría de tiempo de ejecución de JavaScript de Lighthouse sugirió que la secuencia de comandos search-result-v2 ocupó el subproceso principal durante más tiempo que otras secuencias de comandos de la página.

Lectura de fuentes de tareas largas en Lighthouse para el sitio web de Trendyol. Una fuente importante de tareas largas es una secuencia de comandos que controla los resultados de la búsqueda en el PLP de Trendyol.
Auditoría del tiempo de ejecución de JavaScript de Trendyol desde Lighthouse hasta el 5 de septiembre de 2023 por parte de PSI.

Para identificar cuellos de botella en el mundo real, usamos el panel de rendimiento de Chrome DevTools para solucionar los problemas de la experiencia de PLP y también identificar el origen del problema. La emulación del rendimiento en dispositivos móviles con una demora de CPU 4 veces mayor en las Herramientas para desarrolladores de Chrome reveló una tarea larga de 700 a 900 milisegundos en el subproceso principal. Si el subproceso principal está ocupado con otras tareas durante más de 50 milisegundos, es posible que no pueda responder a las entradas del usuario de manera oportuna, lo que generará una mala experiencia del usuario.

Captura de pantalla de una sesión de generación de perfiles de rendimiento en las Herramientas para desarrolladores de Chrome para PLP de Trendyol. La tarea larga que se muestra se ejecuta durante 737.6 milisegundos y forma parte de una devolución de llamada de Intersection Observer.
Generador de perfiles de rendimiento de tareas largas en el PLP de Trendyol, en el panel de rendimiento de las Herramientas para desarrolladores de Chrome.

La tarea más larga se generó por una devolución de llamada de la API de Intersection Observer en la secuencia de comandos de resultados de la búsqueda dentro de un componente de React. En este punto, empezamos a analizar la idea de dividir esa tarea larga en partes pequeñas para darle al navegador más oportunidades de responder a trabajos con mayor prioridad, incluidas las interacciones del usuario.

Resulta que el uso de la operación setState que activa la renderización de React dentro de la devolución de llamada de Intersection Observer tiene un costo alto, lo que puede generar problemas en dispositivos de gama baja, ya que ocupa el subproceso principal durante demasiado tiempo.

Un método que usan los desarrolladores para dividir las tareas en otras más pequeñas incluye setTimeout. Usamos esta técnica para posponer la ejecución de la llamada a setState en una tarea separada. Aunque setTimeout permite diferir la ejecución de JavaScript, no proporciona ningún control sobre la prioridad. Esto nos llevó a unirnos a la prueba de origen scheduler.yield en un esfuerzo por garantizar la continuidad de la ejecución de nuestra secuencia de comandos después de procesar el subproceso 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 });

La incorporación de este método de rendimiento al código de PLP mejoró el INP, ya que la tarea larga principal se dividió en una serie de tareas más pequeñas, lo que permite que el trabajo de mayor prioridad, como las interacciones del usuario y el trabajo de renderización posterior, se realice antes de lo que lo harían de otra forma.

Captura de pantalla de una sesión de generación de perfiles de rendimiento en las Herramientas para desarrolladores de Chrome para PLP de Trendyol. La tarea larga que antes se ejecutaba durante 737.6 milisegundos ahora se divide en varias tareas más pequeñas.
Tarea dividida en otras más pequeñas.

Ten en cuenta que Trendyol usa el framework de PuzzleJs para implementar una arquitectura de microfrontend con React v16.9.0. Con React 18, se podría lograr el mismo rendimiento, pero, por varios motivos, Trendyol no puede actualizar en este momento.

Resultados comerciales

Para medir el impacto de la mejora del INP implementada, ejecutamos una prueba A/B para ver cómo se vieron afectadas las métricas comerciales. En general, nuestros cambios en el PLP generaron una mejora significativa, incluida una reducción del 50% del INP y un aumento del 1% en las tasas de clics desde la página de fichas hasta la página de detalles del producto por sesión de usuario. En la siguiente imagen, puedes ver cómo el INP mejoró en el PPL con el tiempo:

Captura de pantalla del percentil 75 de INP de Trendyol a lo largo de seis meses. Para el final de los seis meses, el INP de Trendyol disminuyó a casi 650 milisegundos, desde casi 1,400 milisegundos.
Mejoras del INP del percentil 75 a lo largo del tiempo.

Conclusión

La optimización de INP es un proceso iterativo y complejo, pero se puede facilitar con un flujo de trabajo claro. Un enfoque sencillo para depurar y mejorar el INP de tu sitio web depende de si recopilas tus propios datos de campo. Si no lo eres, PSI y Lighthouse son un buen punto de partida. Una vez que hayas identificado las páginas con problemas, puedes usar las Herramientas para desarrolladores a fin de realizar una investigación más profunda y reproducir los problemas.

Si cedes ocasionalmente al subproceso principal para que el navegador tenga más oportunidades de realizar trabajos urgentes, tu sitio web será más responsivo, lo que garantizará que tus clientes tengan una mejor experiencia del usuario. Las APIs de programación más nuevas, como scheduler.yield(), facilitan esta tarea.

Agradecemos especialmente a Jeremy Wagner, Barry Pollard y Houssein Djirdeh de Google, y al equipo de Ingeniería de Trendyol por su contribución en este trabajo.