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 Ertragsstrategie die Reaktionsfähigkeit von Publisher-Websites 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. INP wird First Input Delay (FID) im März 2024 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. Dank dieser Empfehlungen können die 9.000 exklusiven Publisher-Partner von Taboola Einnahmen erzielen und ihre Zielgruppen begeistern. 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.

Diese Fallstudie befasst sich mit dem Einsatz von Taboola zur Verbesserung von INP durch den Einsatz der neuen Long Animation Frames (LoAF) API, um die Auswirkungen auf die Seitenreaktionsfähigkeit vor Ort zu messen, und zeigt weitere Bemühungen zur Durchführung spezifischer Optimierungen zur Verbesserung der Nutzererfahrung.

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. der INP, können von einer hohen TBT beeinflusst werden. Eine Untersuchung von Annie Sullivan zur Korrelation zwischen TBT und INP auf Mobilgeräten deutet darauf hin, dass Websites eher gute INP-Werte erzielen, wenn die Blockierzeit des Hauptthreads minimiert wird.

Aufgrund dieser Korrelation und zusammen mit den Bedenken der Verlage und Webpublisher von Taboola bezüglich eines hohen TBT konzentrierte sich Taboola darauf, seinen Beitrag zu diesem Messwert zu minimieren.

Screenshot einer Lighthouse-Prüfung 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 Skript RELEASE.js von Taboola ist für den Großteil der Drittanbieter-Blockierzeit mit 691 Millisekunden 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 aufwies:

  • 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 erkennt nur lange Aufgaben und nicht eine Kombination aus Aufgaben und Layoutänderungen, die zu einer Rendering-Verzögerung führen könnte.

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 über 50 Millisekunden verzögert wird. Statt nur lange Aufgaben zu identifizieren, konnte Taboola die Ursachen für langsame Updates der Benutzeroberfläche ermitteln und die Auswirkungen auf die Reaktionszeit von Seiten in der Praxis analysieren. Die Beobachtung der LoAF hat Taboola ermöglicht:

  1. Zuordnungen von Einträgen zu bestimmten Taboola-Aufgaben
  2. Beobachten Sie Leistungsprobleme bestimmter Funktionen, bevor diese für die 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 Kampagnen 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-Skripteinträ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 erheblich 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. Dieses Design sorgt dafür, dass wichtige nutzerseitige Aufgaben – wie das Rendern von Aktualisierungen – so schnell wie möglich ausgeführt werden können, unabhängig von vorhandenen Aufgaben, die den Hauptthread belegen könnten.

Hier ist das JS-Snippet des Task-Runners „Leistungs-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, was im Hintergrund scheduler.postTask() verwendet (falls die API verfügbar ist) oder auf setTimeout zurückgreift.
  • Diese Funktion umschließt Funktionsaufrufe in Codeabschnitten, die zu langen Animationsframes und INP führen. Diese Codeabschnitte werden in kürzere Aufgaben unterteilt, wodurch die INP reduziert wird.

Unternehmensmesswerte

Dank LoAF konnte Taboola den Einfluss auf INP 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 bestehenden Suchmaschine 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 wirkten sich Geschäftsmesswerte wie die Anzeigenklickrate und der Umsatz pro 1.000 Impressionen (RPM) nicht negativ aus, als TRECS und die Funktion „Performance Fader“ im Testbereich 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 Skripts von Drittanbietern 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.