Cómo Taboola, un proveedor de recomendaciones de contenido, usó la LoAF para mejorar el INP en hasta un 36% para los sitios web de sus socios editores.

Cómo aprovechar la API de Long Animation Frames (LoAF) y adoptar una estrategia de rendimiento inteligente permitió que Taboola mejorara la capacidad de respuesta del sitio web sin comprometer el rendimiento del anuncio.

David Belford
David Belford

Interacción a la siguiente pintura (INP) es una métrica que evalúa la capacidad de respuesta de un sitio web a la entrada del usuario. INP mide el tiempo desde que un usuario comienza una interacción (por ejemplo, cuando hace clic, presiona o escribe) hasta la retroalimentación visual que se genera. INP debe reemplazar el retraso de primera entrada (FID) como Métrica web esencial en marzo de 2024.

Taboola es la plataforma de descubrimiento de contenido líder del mundo, con 500,000 recomendaciones por segundo en la Web abierta. Estas recomendaciones permiten a los 9,000 socios publicadores exclusivos de Taboola monetizar y atraer a sus públicos. Los publicadores renderizan recomendaciones en sus páginas con JavaScript.

Como JavaScript de terceros puede afectar la capacidad de una página para responder rápidamente a las entradas del usuario, Taboola ha invertido mucho en reducir el tamaño de los archivos JavaScript y el tiempo de ejecución. Taboola ha estado rediseñando todo su motor de renderización por completo, así como usando las APIs del navegador directamente sin abstracciones para minimizar su impacto en INP.

Este caso de éxito abarca el recorrido de Taboola para mejorar el INP usando la nueva API de Long Animation Frames (LoAF) para medir su impacto en la capacidad de respuesta de la página en el campo y los esfuerzos posteriores para aplicar optimizaciones específicas para mejorar la experiencia del usuario.

TBT como proxy del INP

Tiempo de bloqueo total (TBT) es una métrica basada en labs que identifica dónde se bloqueó el subproceso principal durante el tiempo suficiente como para afectar la capacidad de respuesta de la página. Las métricas de campo que miden la capacidad de respuesta, como INP, pueden verse afectadas por un TBT alto. Una investigación de Annie Sullivan sobre la correlación entre TBT e INP en dispositivos móviles indica que los sitios tienen más probabilidades de lograr buenas puntuaciones de INP cuando se minimiza el tiempo de bloqueo del subproceso principal.

Esta correlación, junto con la información de los editores en torno a la alta tasa de TBT, lo que llevó a Taboola a enfocar su atención en minimizar su contribución a esta métrica.

Captura de pantalla de una auditoría de Lighthouse para el tiempo del subproceso principal bloqueado. Varias secuencias de comandos bloquearon el subproceso principal en total durante 2,630 milisegundos, y JavaScript de terceros contribuyó con 712 milisegundos en ese tiempo. La secuencia de comandos RELEASE.js de Taboola es responsable de la mayor parte del tiempo de bloqueo de terceros en 691 milisegundos.
Con el antiguo motor de Taboola, las secuencias de comandos como RELEASE.js bloquean el subproceso principal durante 691 milisegundos.

Con TBT como métrica proxy para INP, Taboola comenzó a supervisar y optimizar el tiempo de ejecución de JavaScript para limitar su posible impacto en las Métricas web esenciales. Para comenzar, hizo lo siguiente:

  • Identificar y optimizar secuencias de comandos problemáticas en el campo con la API de Long Tasks
  • Estimación de las contribuciones de TBT mediante el uso de la API de PageSpeed Insights para evaluar entre 10,000 y 15,000 URLs por día

Sin embargo, Taboola se dio cuenta de que analizar la TBT con estas herramientas tenía algunas limitaciones:

  • La API de Long Tasks no puede atribuir la tarea al dominio de origen ni a una secuencia de comandos específica, lo que dificulta la identificación de las fuentes de tareas largas.
  • La API de Long Tasks solo identifica tareas largas, en lugar de una combinación de tareas y cambios de diseño que podrían causar una demora en la renderización.

Para abordar estos desafíos, Taboola se unió a la prueba de origen de la API de Long Animation Frames (LoAF) para comprender mejor su impacto real en la capacidad de respuesta de la entrada del usuario. Las pruebas de origen brindan acceso a funciones nuevas o experimentales, lo que les permite a los desarrolladores probar funciones emergentes que sus usuarios pueden probar por un tiempo limitado.

Es fundamental destacar que el aspecto más difícil de este desafío fue mejorar con éxito INP sin comprometer ningún KPI(indicador clave de rendimiento) de Google Ads ni causar demoras en los recursos para nuestros publicadores.

Uso de LoAF para evaluar el impacto del INP

Un fotograma de animación prolongado se produce cuando una actualización de renderización se retrasa más de 50 milisegundos. Mediante la identificación de las causas de las actualizaciones lentas de la interfaz de usuario, en lugar de solo las tareas largas, Taboola pudo analizar su impacto en la capacidad de respuesta de la página en el campo. Observar loAF permitió a Taboola hacer lo siguiente:

  1. Atribuye entradas a tareas específicas de Taboola.
  2. Observa los problemas de rendimiento en funciones específicas antes de que se implementen en la producción.
  3. Recopila datos agregados para comparar diferentes versiones de código en pruebas A/B y genera informes sobre métricas de éxito clave.

El siguiente JavaScript es una versión simplificada que se usa en producción para recopilar LoAF y aislar el impacto de Taboola.

function loafEntryAnalysis (entry) {
  if (entry.blockingDuration === 0) {
    return;
  }

  let taboolaIsMajor = false;
  const hasInteraction = entry.firstUIEventTimestamp > 0;
  let taboolaDuration = 0;
  const nonTaboolaLoafReport = {};
  const taboolaLoafReport = {};

  entry.scripts.forEach((script) => {
    const taboolaScriptBlockingDuration = handleLongAnimationFrameScript(script, taboolaLoafReport, nonTaboolaLoafReport);
    taboolaDuration += taboolaScriptBlockingDuration;

    if (taboolaScriptBlockingDuration > 0 || taboolaDuration > entry.duration / 2) {
      taboolaIsMajor = true;
    }
  });

  generateToboolaLoafReport(taboolaLoafReport, nonTaboolaLoafReport, hasInteraction, taboolaIsMajor);

  if (hasInteraction) {
    const global = _longAnimationFramesReport.global;
    global.inpBlockingDuration = Math.max(global.inpBlockingDuration, entry.blockingDuration);

    if (taboolaIsMajor) {
      global.taboolaInpBlockingDuration = Math.max(global.taboolaInpBlockingDuration, entry.blockingDuration);
    }
  }
}

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    loafEntryAnalysis(entry);
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });
  • El uso de la función loafEntryAnalysis permitió a Taboola identificar entradas en las que es un colaborador importante.
  • Taboola se considera un colaborador importante si Taboola genera más de la mitad de la duración total de la secuencia de comandos, o si la secuencia tarda más de 50 milisegundos en ejecutarse.
  • Se genera un firstUIEventTimeStamp si la interacción del usuario se retrasa debido a un fotograma de animación largo. La duración del bloqueo más larga se considera la puntuación de INP general. También podemos identificar cuándo Taboola activó una firstUIEventTimeStamp para calcular una puntuación de INP de Taboola.

Los datos recopilados con la LoAF ayudaron a Taboola a crear la siguiente tabla de atribución, en la que se identifican áreas en las que puede aplicar las oportunidades de rendimiento.

.
Secuencia de comandos Duración (milisegundos)
vpaid/units/33_6_8/infra/cmTagINLINE_INSTREAM.js:106517 997
vpaid/units/33_6_8/infra/cmTagFEED_MANAGER.js:496662 561
vpaid/vPlayer/player/v15.8.6/OvaMediaPlayer.js:44631 336
libtrc/impl.20231212-23-RELEASE.js:821090 857
publisher_name/pmk-20220605.5.js:7728 336
libtrc/card-interference-detector.20231219-7-RELEASE.es6.js:183 239
Entradas de la secuencia de comandos de LoAF capturadas por Taboola RUM

TRECS Engine: la nueva estrategia de rendimiento

Además de usar LoAF para comprender mejor las oportunidades de optimización de secuencias de comandos, Taboola está rediseñando todo su motor de renderización para minimizar significativamente la ejecución de JavaScript y el tiempo de bloqueo.

TRECS (servicio de cliente extensible de recomendaciones de Taboola) mantiene la renderización del cliente y el código JS actual del publicador, al tiempo que reduce la cantidad y el tamaño de los archivos obligatorios necesarios para cargar las recomendaciones de Taboola.

Una vez que se identifican las tareas de bloqueo de renderización con LoAF, el Puedes dividir esas tareas antes de ceder al subproceso principal mediante scheduler.postTask(). Este diseño garantiza que el trabajo crucial para el usuario, como la renderización de actualizaciones, se pueda ejecutar lo antes posible, independientemente de cualquier tarea existente que ocupe el subproceso principal.

Este es el fragmento de JS del "Controlador de rendimiento" ejecutor de tareas:

/**
* Send a task to run using the Fader. The task will run using the browser Scheduler, by the configuration settings, or immediately.
* @param task
* @param isBlocker
*/
function sendTaskToFader (task, isBlocker = true) {
  const publisherFaderChoice = fillOptimizationGlobals(); // Loading publisher choice
  const applyYielding = publisherFaderChoice === OptimizationFaderType.Responsiveness;

  if (applyYielding) {
    return runAsPostTask(task, isBlocker);
  }

  return runImmediately(task);
}

/**
* Yielding method using scheduler.postTask and falling back to setTimeout when it's not availabe based on the publisher choice
*/
function runAsPostTask (task, isBlocker = true) {
  if ('scheduler' in window && 'postTask' in scheduler) {
    const priority = isBlocker ? 'user-blocking': 'background';

    return window?.scheduler?.postTask(task, { priority });
  }

  const publisherChoiceEnableFallback = fillPublisherChoices();

  if (publisherChoiceEnableFallback) {
    return new Promise(resolve => {
      window.setTimeout(() => {
        resolve(task());
      }, 0);
    });
  }

  return runImmediately(task);
}

La función sendTaskToFader realiza lo siguiente:

  • Usa runAsPostTask, que utiliza scheduler.postTask() de forma interna (si la API está disponible) o recurre a setTimeout.
  • Esta función une las llamadas a función en secciones de código que generan largos fotogramas de animación e INP. Divide estas secciones de código en tareas más cortas y, por lo tanto, reduce el INP.

Métricas empresariales

Gracias a la LoAF, Taboola pudo comprender mejor su impacto en el INP. La herramienta también destacó las oportunidades de optimización de secuencias de comandos que se podrían utilizar como parte del nuevo motor TRECS.

Para determinar el impacto de TRECS y del atenuador de rendimiento, Taboola realizó una prueba A/B para medir el INP con el motor existente sin que se mostrara secuencias de comandos en un panel de publicadores asociados.

En la siguiente tabla, se muestran los resultados de INP en milisegundos en el percentil 75 de cuatro editores anónimos de la red Taboola.

Publicadores INP con TRECS y atenuador de rendimiento INP con el motor de búsqueda existente Disminución de INP (%)
Publicador A 48 75 36%
Publicador B 153 163 6%
Publicador C 92 135 33%
Publicador D 37 52 29%

Afortunadamente, las métricas empresariales, como la tasa de clics en los anuncios y los ingresos por cada 1,000 impresiones (RPM), no se vieron afectadas cuando se habilitaron TRECS y el atenuador de rendimiento en el panel de pruebas. Con esta mejora positiva en INP sin ningún resultado negativo como se esperaba en los KPI de Google Ads, Taboola mejorará gradualmente el rendimiento de sus publicadores la percepción sobre el producto.

Otro Lighthouse ejecutado en el mismo cliente que se destacó anteriormente demuestra una mejora significativa en el tiempo de bloqueo del subproceso principal por parte de Taboola cuando se usa el nuevo motor.

Captura de pantalla de una auditoría de Lighthouse para el tiempo del subproceso principal bloqueado después de que se aplicaran los nuevos motores TRECS y Performance Fader para mejorar el tiempo de bloqueo del subproceso principal. La auditoría se redujo a solo 206 milisegundos, en comparación con 712 antes de que se realizaran optimizaciones.
El nuevo motor de Taboola ayudó a secuencias de comandos como RELEASE.js a reducir la TBT en 485 ms (-70%).

Esto demuestra que el uso de LoAF para identificar las causas de INP y la implementación de las técnicas de rendimiento posteriores con el atenuador de rendimiento permite a los socios de Taboola lograr el máximo éxito en el rendimiento del anuncio y la página.

Conclusión

La optimización de INP es un proceso complejo, sobre todo cuando se usan secuencias de comandos de terceros en sitios web asociados. Antes de que comience la optimización, la atribución de INP a secuencias de comandos específicas quita las conjeturas y los posibles daños a otras métricas de rendimiento del sitio.La API de LoAF ha demostrado ser una herramienta valiosa para identificar y abordar problemas de INP, particularmente para los terceros incorporados, ya que les permite identificar sus oportunidades específicas de mejora del SDK y eliminar la interferencia de otras tecnologías presentes en la página.

Cuando se usa junto con una buena estrategia de rendimiento, como scheduler.postTask(), loAF puede ayudarte a observar y comprender la causa de una mala respuesta de la página, lo que, a su vez, te brinda la información que necesitas para mejorar el INP de tu sitio web.

Queremos dar un agradecimiento especial a Gilberto Cocchi, Noam Rosenthal y Rick Viscomi de Google, y a Dedi Hakak, Anat Dagan y Omri Ariav del equipo de Ingeniería y Producto de Taboola por su contribución a este trabajo.