Cómo aprovechar la API de Long Animation Frames (LoAF) y adoptar una estrategia de rendimiento inteligente permitió a Taboola mejorar la capacidad de respuesta de los sitios web de los publicadores sin comprometer el rendimiento de los anuncios.
Interaction to Next Paint (INP) es una métrica que evalúa la capacidad de respuesta de un sitio web a las entradas del usuario. El INP mide el tiempo que transcurre desde que un usuario comienza una interacción (por ejemplo, cuando hace clic, presiona o escribe) hasta la respuesta visual resultante. El INP reemplazará al retraso de primera entrada (FID) como Métrica web esencial en marzo de 2024.
Taboola es la plataforma de descubrimiento de contenido líder en el mundo, que impulsa 500,000 recomendaciones por segundo en la Web abierta. Estas recomendaciones permiten que los 9,000 socios publicadores exclusivos de Taboola moneticen a su público y lo atraigan. Los publicadores renderizan las recomendaciones en sus páginas con JavaScript.
Dado que el código 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 sus archivos JavaScript y el tiempo de ejecución. Taboola rediseñó todo su motor de renderización y usa las APIs del navegador directamente sin abstracciones para minimizar su impacto en el INP.
En este caso de estudio, se describe el recorrido de Taboola para mejorar el INP con 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 que mejoren la experiencia del usuario.
El TBT como proxy del INP
El Total Blocking Time (TBT) es una métrica basada en el lab 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 el INP, pueden verse afectadas por un TBT alto. Una investigación de Annie Sullivan sobre la correlación entre el TBT y el INP en dispositivos móviles indica que es más probable que los sitios obtengan buenas puntuaciones de INP cuando se minimiza el tiempo de bloqueo del subproceso principal.
Esta correlación, junto con las preocupaciones de los publicadores de Taboola sobre el TBT alto, llevó a Taboola a centrar su atención en minimizar su contribución a esta métrica.
RELEASE.js bloquean el subproceso principal durante 691 milisegundos.
Taboola comenzó a supervisar y optimizar el tiempo de ejecución de JavaScript para limitar su posible impacto en las Métricas web esenciales, utilizando el TBT como métrica proxy del INP. Comenzaron por hacer lo siguiente:
- Identificar y optimizar los scripts problemáticos en el campo con la API de Long Tasks
- Estimamos las contribuciones del TBT con la API de PageSpeed Insights para evaluar entre 10,000 y 15,000 URLs por día.
Sin embargo, Taboola notó que analizar el 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 en particular, lo que dificulta la identificación de las fuentes de tareas largas.
- La API de Long Tasks solo identifica las 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) con el objetivo de comprender mejor su impacto real en la capacidad de respuesta a la entrada del usuario. Las pruebas de origen brindan acceso a funciones nuevas o experimentales, lo que permite a los desarrolladores probar funciones emergentes que sus usuarios pueden probar por tiempo limitado.
Es fundamental destacar que el aspecto más difícil de este desafío fue mejorar el INP sin comprometer ningún KPI(indicador clave de rendimiento) de los anuncios ni causar demoras en los recursos para nuestros publicadores.
Cómo usar LoAF para evaluar el impacto del INP
Un fotograma de animación largo se produce cuando una actualización de renderización se retrasa más de 50 milisegundos. Al identificar 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. La observación de LoAF permitió a Taboola hacer lo siguiente:
- Atribuye entradas a tareas específicas de Taboola.
- Observa los problemas de rendimiento en funciones específicas antes de que se implementen en producción.
- Recopilamos datos agregados para comparar diferentes versiones de código en las pruebas A/B y generamos informes sobre las métricas clave de éxito.
El siguiente código JavaScript es una versión simplificada que se usa en producción para recopilar el 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
loafEntryAnalysispermitió que Taboola identificara las entradas en las que es un colaborador importante. - Se considera que Taboola es un colaborador importante si más de la mitad de la duración total de la secuencia de comandos se debe a Taboola o si una secuencia de comandos de Taboola tarda más de 50 milisegundos en ejecutarse.
- Se genera un
firstUIEventTimeStampsi la interacción del usuario se retrasa debido a un fotograma de animación largo. La duración de bloqueo más larga se considera la puntuación general del INP. También podemos identificar cuándo Taboola activó unfirstUIEventTimeStamppara calcular una puntuación de INP de Taboola.
Los datos recopilados con LoAF ayudaron a Taboola a crear la siguiente tabla de atribución, que identifica las áreas en las que se pueden aplicar oportunidades de rendimiento.
Motor de TRECS: La nueva estrategia de rendimiento
Además de usar LoAF para comprender mejor las oportunidades de optimización de secuencias de comandos, Taboola rediseñó todo su motor de renderización para minimizar significativamente el tiempo de bloqueo y ejecución de JavaScript.
TRECS (Taboola Recommendations Extensible Client Service) mantiene la renderización del cliente y el código JS actual del publicador, a la vez 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 que bloquean la renderización con LoAF, el "Performance Fader" puede dividir esas tareas antes de ceder el control al subproceso principal con scheduler.postTask(). Este diseño garantiza que el trabajo crucial orientado al usuario, como las actualizaciones de renderización, se pueda ejecutar lo antes posible, independientemente de las tareas existentes que puedan ocupar el subproceso principal.
A continuación, se muestra el fragmento de JS del ejecutor de tareas "Performance Fader":
/**
* 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 usascheduler.postTask()de forma interna (si la API está disponible) o recurre asetTimeout. - Esta función encapsula las llamadas a funciones en secciones de código que provocan fotogramas de animación largos y un INP alto. Divide estas secciones de código en tareas más cortas y, por lo tanto, reduce el INP.
Métricas empresariales
Gracias a 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 usar como parte del nuevo motor de TRECS.
Para determinar el impacto de TRECS y el Performance Fader, Taboola realizó una prueba A/B en la que se midió el INP en comparación con el motor existente sin la generación de scripts en un panel de socios publicadores.
En la siguiente tabla, se muestran los resultados del INP en milisegundos en el percentil 75 de cuatro publicadores anónimos en la red de Taboola.
Afortunadamente, las métricas comerciales, como el porcentaje de clics de los anuncios y los ingresos por cada 1,000 impresiones (RPM), no se vieron afectadas de forma negativa cuando se habilitaron TRECS y el Performance Fader en el panel de pruebas. Con esta mejora positiva en el INP sin ningún resultado negativo como se esperaba en los KPI de los anuncios, Taboola mejorará gradualmente la percepción de sus publicadores sobre su producto.
Otra ejecución de Lighthouse en el mismo cliente que se destacó anteriormente demuestra una mejora significativa en el tiempo de bloqueo del subproceso principal de Taboola cuando se usa el nuevo motor.
RELEASE.js a reducir el TBT en 485 ms (-70%).
Esto demuestra que usar LoAF para identificar las causas del INP y, luego, implementar las técnicas de rendimiento con el Performance Fader permite que los socios de Taboola alcancen el máximo éxito en el rendimiento de los anuncios y las páginas.
Conclusión
La optimización del INP es un proceso complejo, en especial cuando se usan secuencias de comandos de terceros en los sitios web de socios. Antes de que comience la optimización, la atribución del INP a secuencias de comandos específicas elimina cualquier suposición y posible daño a otras métricas de rendimiento del sitio.La API de LoAF demostró ser una herramienta valiosa para identificar y abordar los problemas de INP, en especial para los terceros integrados, ya que les permite identificar sus oportunidades específicas de mejora del SDK y, al mismo tiempo, eliminar la interferencia de otras tecnologías presentes en la página.
Cuando se usa en conjunto con una buena estrategia de cesión, como el uso de scheduler.postTask(), LoAF puede ayudarte a observar y comprender la causa de la mala capacidad de 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.
Agradecemos especialmente 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.