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

Taboola konnte mithilfe der Long Animation Frames API (LoAF) und einer intelligenten Ertragsstrategie die Reaktionszeit der Publisher-Websites verbessern, ohne die Anzeigenleistung zu beeinträchtigen.

David Belford
David Belford

Interaction to Next Paint (INP) ist ein Messwert, der die Reaktionsfähigkeit einer Website auf Nutzereingaben bewertet. INP misst die Zeit ab dem Beginn einer Interaktion des Nutzers – z. B. dem Klicken, Tippen oder Tippen – bis zum visuellen Feedback. INP wird im März 2024 First Input Delay (FID) als Core Web Vital ersetzen.

Taboola ist die weltweit führende Plattform zum Finden von Inhalten, die 500.000 Empfehlungen pro Sekunde im offenen Web bereitstellt. Dank dieser Empfehlungen können die 9.000 exklusiven Publisher-Partner von Taboola ihre Zielgruppen monetarisieren und mit ihnen interagieren. Publisher rendern Empfehlungen auf ihren Seiten mithilfe von JavaScript.

Da Drittanbieter-JavaScript die Fähigkeit einer Seite beeinflussen kann, schnell auf Nutzereingaben zu reagieren, hat Taboola umfassend investiert, um die Größe der JavaScript-Dateien zu reduzieren und die Ausführungszeit zu reduzieren. Taboola hat sein gesamtes Rendering-Modul neu gestaltet und verwendet Browser-APIs direkt und ohne Abstraktionen, um die Auswirkungen auf INP zu minimieren.

Diese Fallstudie befasst sich mit dem Weg von Taboola zur Verbesserung von INP, indem die neue Long Animation Frames (LoAF) API verwendet wurde, um deren Auswirkungen auf die Seitenreaktionsfähigkeit in der Praxis zu messen, und die nachfolgenden Bemühungen, spezifische Optimierungen zur Verbesserung der User Experience anzuwenden.

TBT als Proxy von INP

Die Total Blocking Time (TBT) ist ein Lab-basierter Messwert, der angibt, wo der Hauptthread lange genug blockiert wurde, um sich wahrscheinlich auf die Reaktionszeit der Seite zu auswirken. Feldmesswerte, die die Reaktionsfähigkeit messen, z. B. INP, können durch eine hohe TBT beeinträchtigt werden. Eine Untersuchung von Annie Sullivan zur Korrelation zwischen TBT und INP auf Mobilgeräten zeigt, dass Websites eher gute INP-Werte erzielen, wenn die Blockierungszeit des Hauptthreads minimiert wird.

Diese Korrelation, kombiniert mit den Bedenken der Publisher bezüglich einer hohen TBT, veranlasste Taboola, seinen Fokus auf die Minimierung seines Beitrags zu diesem Messwert zu richten.

Screenshot einer Lighthouse-Prüfung auf blockierte Zeit für den Hauptthread. Der Hauptthread wurde insgesamt 2.630 Millisekunden lang von mehreren Skripts blockiert, wobei JavaScript von Drittanbietern 712 Millisekunden beigetragen hat. Das Skript RELEASE.js von Taboola ist für den Großteil der Drittanbieter-Blockierzeit mit 691 Millisekunden verantwortlich.
Bei der alten Engine von Taboola blockieren Skripts wie RELEASE.js den Hauptthread 691 Millisekunden.

Taboola nutzte „TBT“ als Proxymesswert für INP und begann, die JavaScript-Ausführungszeit zu beobachten und zu optimieren, um die möglichen Auswirkungen auf die Core Web Vitals zu begrenzen. Zuerst ging er so vor:

  • Mithilfe der Long Tasks API problematische Skripts vor Ort identifizieren und optimieren
  • Schätzung der TBT-Beiträge mithilfe der PageSpeed Insights API zur Bewertung von 10.000 bis 15.000 URLs pro Tag

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

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

Taboola nahm am Ursprungstest der Long Animation Frames (LoAF) API teil, um die tatsächlichen Auswirkungen auf die Reaktionszeit von Nutzereingaben besser zu verstehen. Mit Ursprungstests erhalten Entwickler Zugriff auf neue oder experimentelle Funktionen, mit denen Entwickler neue Funktionen testen können, die ihre Nutzer für eine begrenzte Zeit testen können.

Betonen Sie unbedingt, dass die größte Herausforderung bei dieser Herausforderung darin bestand, INP erfolgreich zu verbessern, ohne Google Ads-KPIs(Key Performance Indicator, Leistungsindikator) zu gefährden oder Ressourcenverzögerungen für unsere Publisher zu verursachen.

LoAF zur Bewertung der INP-Auswirkungen verwenden

Ein langer Animationsframe tritt auf, wenn eine Rendering-Aktualisierung mehr als 50 Millisekunden verzögert wird. Taboola erkannte die Ursachen für langsame Aktualisierungen der Benutzeroberfläche und nicht nur für langwierige Aufgaben. So konnte Taboola die Auswirkungen auf die Seitenreaktion in der Praxis analysieren. Die Beobachtung von LoAF hat Taboola Folgendes ermöglicht:

  1. Attributeinträge zu bestimmten Taboola-Aufgaben zuweisen.
  2. Beobachten Sie Leistungsprobleme bei bestimmten Features, bevor sie für die Produktion bereitgestellt werden.
  3. Sammeln Sie aggregierte Daten, um verschiedene Codeversionen in A/B-Tests zu vergleichen und Berichte zu wichtigen Erfolgsmesswerten zu erstellen.

Das folgende JavaScript ist eine vereinfachte Version, die in der Produktion zur Erfassung 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 Funktion loafEntryAnalysis konnte Taboola Einträge identifizieren, bei denen es eine wichtige Rolle spielt.
  • Taboola gilt als Hauptbeitragender, wenn mehr als die Hälfte der gesamten Skriptdauer durch Taboola verursacht wird oder ein Taboola-Skript mehr als 50 Millisekunden zur Ausführung benötigt.
  • Wenn sich eine Nutzerinteraktion aufgrund eines langen Animations-Frames verzögert, wird ein firstUIEventTimeStamp generiert. Die längste Blockierungsdauer wird als INP-Gesamtwert betrachtet. Wir können auch erkennen, ob Taboola einen firstUIEventTimeStamp ausgelöst hat, um einen Taboola INP-Score zu berechnen.

Die mit LoAF erfassten Daten halfen Taboola bei der Erstellung der folgenden Zuordnungstabelle, die Bereiche aufzeigt, in denen sich Profitchancen anwenden lassen.

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
Von Taboola RUM erfasste LoAF-Skripteinträge

TRECS Engine: die neue Ertragsstrategie

Neben der Nutzung von LoAF, um die Möglichkeiten der Skriptoptimierung besser zu verstehen, hat Taboola sein gesamtes Rendering-Modul neu gestaltet, um die Ausführung und Blockierung von JavaScript zu minimieren.

TRECS (Taboola Recommendations Extensible Client Service) unterstützt das clientseitige Rendering und den aktuellen JS-Code des Publishers bei gleichzeitiger Reduzierung der Anzahl und Größe der erforderlichen Dateien, die zum Laden der Empfehlungen von Taboola erforderlich sind.

Sobald die Aufgaben, die das Rendering blockieren, mithilfe von LoAF identifiziert wurden, kann der „Performance Fader“ diese Aufgaben aufteilen, bevor er mit scheduler.postTask() an den Hauptthread übergeben wird. Dieses Design sorgt dafür, dass wichtige nutzerseitige Arbeiten – wie z. B. das Rendern von Aktualisierungen – so schnell wie möglich ausgeführt werden können, unabhängig von vorhandenen Aufgaben, die den Hauptthread möglicherweise 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, wodurch im Hintergrund scheduler.postTask() verwendet wird (wenn die API verfügbar ist) oder auf setTimeout zurückgreifen.
  • Diese Funktion umschließt Funktionsaufrufe in Codeabschnitten, die lange Animationsframes und INP verursachen. Diese Codeabschnitte werden in kürzere Aufgaben aufgeteilt und somit der INP reduziert.

Geschäftsmesswerte

Dank LoAF konnte Taboola die Auswirkungen auf INP besser nachvollziehen. Außerdem zeigte das Tool Möglichkeiten zur Skriptoptimierung, die im Rahmen der neuen TRECS-Engine genutzt werden könnten.

Um die Auswirkungen von TRECS und dem Performance Fader zu ermitteln, führte Taboola einen A/B-Test durch, bei dem die INP mit der vorhandenen Engine verglichen wurde, ohne ein Script für eine Gruppe von Publisher-Partnern zu liefern.

Die folgende Tabelle zeigt INP-Ergebnisse in Millisekunden beim 75. Perzentil von vier anonymen Publishern im Taboola-Netzwerk.

Publisher INP mit TRECS und Performance Fader INP mit der vorhandenen Suchmaschine Rückgang des INP (%)
Publisher A 48 75 36 %
Publisher B 153 163 6 %
Publisher C 92 135 33 %
Publisher D 37 52 29 %

Glücklicherweise wurden Unternehmensmesswerte wie die Anzeigenklickrate und der Umsatz pro 1.000 Impressionen (RPM) nicht negativ beeinflusst, wenn TRECS und der Leistungseinblendung im Testbereich aktiviert wurden. Dank dieser positiven INP-Verbesserung ohne negatives Ergebnis bei den Google Ads-KPIs wird Taboola die Wahrnehmung seines Produkts durch die Publisher nach und nach verbessern.

Ein weiterer Lighthouse, der zuvor für denselben Kunden ausgeführt wurde, zeigt eine deutliche Verbesserung der Zeit, die Taboola beim Einsatz des Hauptthreads blockiert.

Screenshot einer Lighthouse-Prüfung zur blockierten Zeit des Hauptthreads, nachdem die neuen TRECS- und Performance Fader-Engines angewendet wurden, um die Sperrzeit des Hauptthreads zu verbessern. Die Prüfung sank auf nur 206 Millisekunden im Vergleich zu 712 Millisekunden vor der Optimierung.
Die neue Engine von Taboola half bei Skripts wie RELEASE.js, die TBT um 485 ms (-70%) zu reduzieren.

Das zeigt, dass Taboolas Partner mithilfe von LoAF, INP-Ursachen und mit dem Performance-Fader die nachfolgenden Erträge zur Erzielung von maximalem Erfolg bei der Anzeigen- und Seitenleistung nutzen können.

Fazit

Die Optimierung von INP ist ein komplexer Prozess, insbesondere wenn Drittanbieter-Scripts auf Partnerwebsites verwendet werden. Bevor die Optimierung beginnen kann, werden durch die Zuordnung von INP zu bestimmten Skripts alle Unsicherheiten und potenzielle Schäden an anderen Website-Leistungsmesswerten vermieden. Die LoAF API hat sich als wertvolles Tool zur Identifizierung und Behebung von INP-Problemen erwiesen, insbesondere für eingebettete Drittanbieter. Sie ermöglicht es ihnen, ihre spezifischen SDK-Verbesserungsmöglichkeiten zu ermitteln und gleichzeitig Störungen durch andere Technologien auf der Seite zu vermeiden.

In Kombination mit einer guten Ertragsstrategie wie scheduler.postTask() kann LoAF dabei helfen, die Ursache für eine schlechte Seitenreaktionszeit zu beobachten und zu verstehen. Dadurch erhalten Sie die Informationen, die Sie zur Verbesserung des INP Ihrer Website benötigen.

Wir danken ganz besonders Gilberto Cocchi, Noam Rosenthal und Rick Viscomi von Google sowie Dedi Hakak, Anat Dagan und Omri Ariav vom Engineering- und Produktteam von Taboola für ihren Beitrag zu dieser Arbeit.