Wie der Anbieter von Inhaltsempfehlungen Taboola mithilfe von LoAF die INP-Leistung für seine Publisher-Partnerwebsites um bis zu 36% verbesserte.

Wie Taboola mithilfe der Long Animation Frames API (LoAF) und einer intelligenten Yield-Strategie die Reaktionsfähigkeit der Websites von Publishern verbessern konnte, ohne die Anzeigenleistung zu beeinträchtigen.

David Belford
David Belford

Interaction to Next Paint (INP) ist ein Messwert, mit dem die Reaktionsfähigkeit einer Website auf Nutzereingaben bewertet wird. Mit INP wird die Zeit gemessen, die vergeht, bis ein Nutzer eine Interaktion beginnt, z. B. durch Klicken, Tippen oder Tippen, und bis das visuelle Feedback erscheint. Im März 2024 wird INP den Messwert „First Input Delay“ (FID) als Core Web Vital ersetzen.

Taboola ist die weltweit führende Plattform für die Entdeckung von Inhalten. Sie ermöglicht 500.000 Empfehlungen pro Sekunde im offenen Web. Mit diesen Empfehlungen können die 9.000 exklusiven Publisher-Partner von Taboola ihre Zielgruppen monetarisieren und mit ihnen interagieren. Publisher rendern Empfehlungen auf ihren Seiten mit JavaScript.

Da JavaScript von Drittanbietern die Fähigkeit einer Seite beeinträchtigen kann, schnell auf Nutzereingaben zu reagieren, hat Taboola viel in die Verringerung der Größe und Ausführungszeit von JavaScript-Dateien investiert. Taboola hat seine gesamte Rendering-Engine neu gestaltet und verwendet Browser-APIs direkt ohne Abstraktion, um die Auswirkungen auf die INP zu minimieren.

In dieser Fallstudie wird beschrieben, wie Taboola die INP mithilfe der neuen LoAF API (Long Animation Frames) verbessert hat, um die Auswirkungen auf die Seitenreaktionsfähigkeit in der Praxis zu messen. Außerdem werden die anschließenden Bemühungen beschrieben, bestimmte Optimierungen zur Verbesserung der Nutzerfreundlichkeit vorzunehmen.

TBT als Proxy für INP

Die Gesamte Blockierzeit ist ein LAB-basierter Messwert, der angibt, wann der Haupt-Thread lange genug blockiert wurde, um die Reaktionsfähigkeit der Seite wahrscheinlich zu beeinträchtigen. Feldmesswerte, die die Reaktionsfähigkeit messen, wie z. B. INP, können von einer hohen TBT beeinflusst werden. Eine Untersuchung von Annie Sullivan zur Korrelation zwischen TBT und INP auf Mobilgeräten zeigt, dass Websites mit größerer Wahrscheinlichkeit gute INP-Werte erzielen, wenn die Blockierungszeit des Haupt-Threads minimiert wird.

Diese Korrelation und die Bedenken der Taboola-Publisher hinsichtlich hoher TBT-Werte haben dazu geführt, dass Taboola seinen Beitrag zu diesem Messwert minimiert hat.

Ein Screenshot einer Lighthouse-Analyse für die blockierte Zeit des Hauptthreads Der Hauptthread wurde insgesamt von mehreren Scripts für 2.630 Millisekunden blockiert, wobei JavaScript von Drittanbietern 712 Millisekunden zu dieser Zeit beitrug. Das RELEASE.js-Script von Taboola ist mit 691 Millisekunden für den Großteil der Blockierungszeit von Drittanbietern verantwortlich.
Mit der alten Taboola-Engine blockieren Scripts wie RELEASE.js den Hauptthread für 691 Millisekunden.

Taboola nutzte TBT als Proxymesswert für INP und begann, die JavaScript-Ausführungszeit zu überwachen und zu optimieren, um die potenziellen Auswirkungen auf die Core Web Vitals zu begrenzen. Dazu hat er Folgendes getan:

  • Mit der Long Tasks API problematische Scripts im Feld identifizieren und optimieren
  • TBT-Beiträge werden anhand der PageSpeed Insights API geschätzt, um täglich 10.000 bis 15.000 URLs zu bewerten.

Taboola stellte jedoch fest, dass die Analyse von TBT mit diesen Tools einige Einschränkungen aufweist:

  • Die Long Tasks API kann die Aufgabe nicht der Ursprungsdomain oder einem bestimmten Script zuordnen. Das erschwert die Identifizierung der Quellen langer Aufgaben.
  • Die Long Tasks API identifiziert nur lange Aufgaben, keine Kombination aus Aufgaben und Layoutänderungen, die zu einer Renderingverzögerung führen können.

Um diese Herausforderungen zu meistern, nahm Taboola am Ursprungstest der Long Animation Frames API (LoAF) teil, um die tatsächlichen Auswirkungen auf die Reaktionsfähigkeit der Nutzereingabe besser zu verstehen. Ursprungstests gewähren Zugriff auf neue oder experimentelle Funktionen. So können Entwickler neue Funktionen testen, die ihre Nutzer für begrenzte Zeit ausprobieren können.

Der schwierigste Aspekt dieser Herausforderung bestand darin, die Anzeigenbereitstellung zu verbessern, ohne die KPIs von Google Ads zu beeinträchtigen oder Verzögerungen bei der Ressourcenbereitstellung für unsere Publisher zu verursachen.

LoAF zur Bewertung der Auswirkungen von Anzeigenaufträgen verwenden

Ein langer Animationsframe tritt auf, wenn eine Rendering-Aktualisierung länger als 50 Millisekunden dauert. Indem Taboola die Ursachen für langsame Updates der Benutzeroberfläche ermittelte und nicht nur lange Aufgaben, konnte das Unternehmen die Auswirkungen auf die Seitenreaktionsfähigkeit in der Praxis analysieren. Durch die Beobachtung von LoAF konnte Taboola Folgendes erreichen:

  1. Zuordnungen von Einträgen zu bestimmten Taboola-Aufgaben
  2. Leistungsprobleme bei bestimmten Funktionen beobachten, bevor sie in der Produktion bereitgestellt werden
  3. Aggregierte Daten erfassen, um verschiedene Codeversionen in A/B-Tests zu vergleichen, und Berichte zu wichtigen Erfolgsmesswerten erstellen

Das folgende JavaScript ist eine vereinfachte Version, die in der Produktion zum Erfassen von LoAF verwendet wird, um die Auswirkungen von Taboola zu isolieren.

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 });
  • Mithilfe der loafEntryAnalysis-Funktion konnte Taboola Einträge identifizieren, bei denen es ein wichtiger Mitwirkender ist.
  • Taboola gilt als Hauptursache, wenn mehr als die Hälfte der gesamten Scriptdauer auf Taboola zurückzuführen ist oder die Ausführung eines Taboola-Scripts mehr als 50 Millisekunden dauert.
  • Ein firstUIEventTimeStamp wird generiert, wenn die Nutzerinteraktion aufgrund eines langen Animationsframes verzögert wird. Die längste Blockierungsdauer wird als Gesamt-INP-Wert betrachtet. Wir können auch erkennen, wann Taboola eine firstUIEventTimeStamp ausgelöst hat, um einen Taboola-INP-Wert zu berechnen.

Anhand der mit LoAF erfassten Daten konnte Taboola die folgende Attributionstabelle erstellen, in der Bereiche mit aussichtsreichen Ergebnissen identifiziert werden.

Script Dauer (Millisekunden)
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
LoAF-Scripteinträge, die von Taboola RUM erfasst wurden

TRECS-Engine: Die neue Yielding-Strategie

Taboola nutzt LoAF nicht nur, um Optimierungsmöglichkeiten für Scripts besser zu verstehen, sondern hat auch seine gesamte Rendering-Engine neu gestaltet, um die JavaScript-Ausführung und Blockierungszeit deutlich zu minimieren.

TRECS (Taboola Recommendations Extensible Client Service) behält das clientseitige Rendering und den aktuellen JS-Code des Publishers bei und reduziert gleichzeitig die Anzahl und Größe der erforderlichen Dateien, die zum Laden der Empfehlungen von Taboola erforderlich sind.

Sobald renderblockierende Aufgaben mit LoAF identifiziert wurden, kann der „Leistungs-Dimmer“ diese Aufgaben aufteilen, bevor er mit scheduler.postTask() an den Hauptthread übergibt. Durch dieses Design können wichtige nutzerorientierte Aufgaben wie Rendering-Updates so schnell wie möglich ausgeführt werden, unabhängig von vorhandenen Aufgaben, die den Hauptthread belegen.

Hier ist das JS-Snippet des Task-Runners „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);
}

Die sendTaskToFader-Funktion:

  • Verwendet runAsPostTask, das intern scheduler.postTask() verwendet (sofern die API verfügbar ist), oder greift auf setTimeout zurück.
  • Diese Funktion umschließt Funktionsaufrufe in Codeabschnitten, die zu langen Animationsframes und INP führen. Es unterteilt diese Codeabschnitte in kürzere Aufgaben und reduziert so die INP.

Unternehmensmesswerte

Dank LoAF konnte Taboola die Auswirkungen auf die Anzeigenleistung besser nachvollziehen. Außerdem wurden Optimierungsmöglichkeiten für Scripts aufgezeigt, die im Rahmen der neuen TRECS-Engine genutzt werden können.

Um die Auswirkungen von TRECS und des Leistungsausblendens zu ermitteln, führte Taboola einen A/B-Test durch, bei dem die INP mit der bestehenden Engine ohne Script-Ausgabe in einem Publisher-Panel verglichen wurde.

In der folgenden Tabelle sind die INP-Ergebnisse in Millisekunden für den 75. Perzentilwert von vier anonymen Publishern im Taboola-Netzwerk aufgeführt.

Publisher INP mit TRECS + Leistungs-Fader INP mit der vorhandenen Engine INP-Rückgang (%)
Publisher A 48 75 36 %
Publisher B 153 163 6 %
Publisher C 92 135 33 %
Publisher D 37 52 29 %

Glücklicherweise wurden die Geschäftsmesswerte wie die Anzeigenklickrate und der Umsatz pro 1.000 Impressionen (RPM) nicht negativ beeinflusst, als TRECS und der Leistungsdimmer im Testpanel aktiviert wurden. Durch diese positive Verbesserung der INP ohne negative Auswirkungen auf die KPIs für Anzeigen wird Taboola die Wahrnehmung seines Produkts bei Publishern nach und nach verbessern.

Ein weiterer Lighthouse-Lauf für denselben Kunden, der bereits erwähnt wurde, zeigt eine deutliche Verbesserung der Blockierungszeit des Hauptthreads durch Taboola bei Verwendung der neuen Engine.

Screenshot einer Lighthouse-Analyse für die Blockierungszeit des Hauptthreads, nachdem die neuen TRECS- und Performance-Fader-Engines angewendet wurden, um die Blockierungszeit des Hauptthreads zu verbessern. Die Prüfung wurde auf nur 206 Millisekunden reduziert, verglichen mit 712 Millisekunden vor den Optimierungen.
Mit der neuen Taboola-Engine konnte bei Scripts wie RELEASE.js die Anzeigenauslieferungszeit um 485 ms (– 70%) reduziert werden.

Das zeigt, dass die Partner von Taboola mithilfe von LoAF die Ursachen von Anzeigenauslieferungsproblemen ermitteln und die anschließenden Yielding-Techniken mit dem Performance Fader einsetzen können, um die Anzeigen- und Seitenleistung zu maximieren.

Fazit

Die Optimierung von INP ist ein komplexer Prozess, insbesondere wenn auf Partnerwebsites Drittanbieter-Scripts verwendet werden. Bevor mit der Optimierung begonnen werden kann, werden INP-Probleme bestimmten Scripts zugeordnet, um Vermutungen und potenzielle Schäden an anderen Website-Leistungsmesswerten auszuschließen. Die LoAF API hat sich als wertvolles Tool für die Erkennung und Behebung von INP-Problemen erwiesen, insbesondere für eingebettete Drittanbieter. So können sie ihre spezifischen SDK-Verbesserungsmöglichkeiten ermitteln und gleichzeitig Störungen durch andere auf der Seite vorhandene Technologien beseitigen.

In Kombination mit einer guten Ertragsstrategie, z. B. mit scheduler.postTask(), können Sie mit LoAF die Ursache für eine schlechte Seitenreaktionsfähigkeit beobachten und verstehen. So erhalten Sie die Informationen, die Sie benötigen, um die INP Ihrer Website zu verbessern.

Ein besonderer Dank geht an Gilberto Cocchi, Noam Rosenthal und Rick Viscomi von Google sowie an Dedi Hakak, Anat Dagan und Omri Ariav vom Engineering- und Produktteam von Taboola für ihren Beitrag zu dieser Arbeit.