Jak dostawca rekomendacji treści, firma Taboola, użyła LoAF, by zwiększyć wartość INP w witrynach partnerów wydawców nawet o 36%.

Jak wykorzystanie interfejsu Long Animation Frames API (LoAF) i wdrożenie inteligentnej strategii zysku pozwoliły firmie Taboola poprawić responsywność witryny wydawcy bez pogorszenia skuteczności reklam.

David Belford
David Belford

Interakcja z kolejnym wyrenderowaniem (INP) to dane, które pozwalają ocenić responsywność witryny w odniesieniu do danych wejściowych użytkownika. INP mierzy czas od rozpoczęcia interakcji przez użytkownika – np. kliknięcia, dotknięcia lub pisania – do wyniku wizualnego. W marcu 2024 r. wartość INP zastąpi opóźnienie przy pierwszym działaniu (FID) jako podstawowy wskaźnik internetowy.

Taboola to najpopularniejsza na świecie platforma do odkrywania treści, która na sekundę udostępnia w otwartej sieci 500 tys. rekomendacji. Dzięki tym rekomendacjom 9000 wyłącznych wydawców firmy Taboola może zarabiać i angażować odbiorców. Wydawcy renderują rekomendacje na swoich stronach za pomocą JavaScriptu.

Ponieważ kod JavaScript innych firm może wpływać na możliwość szybkiej reakcji strony na dane wprowadzane przez użytkownika, firma Taboola poświęciła dużo czasu na zmniejszenie rozmiaru plików JavaScript i skrócenia czasu ich wykonywania. Firma Taboola zmieniła cały swój silnik renderowania, a także bezpośrednio używa interfejsów API przeglądarek bez konieczności stosowania abstrakcji, aby zminimalizować wpływ na INP.

To studium przypadku przedstawia wpływ firmy Taboola na poprawę wartości INP za pomocą nowego interfejsu API Long Animation Frames (LoAF) do pomiaru jej wpływu na czas reagowania strony w tej dziedzinie oraz działania mające na celu zastosowanie określonych optymalizacji w celu poprawy wygody użytkowników.

TBT jako serwer proxy INP

Całkowity czas blokowania (TBT) to dane z laboratorium, które wskazują, gdzie wątek główny był zablokowany na wystarczająco długo, aby prawdopodobnie wpływać na czas reagowania strony. Duża wartość TBT może wpływać na dane pól, które mierzą czas reakcji (np. INP). Badanie przeprowadzone przez Annie Sullivan nad korelacją między TBT a INP na urządzeniach mobilnych wskazuje, że witryny mają większe szanse na uzyskanie dobrych wyników INP przy skróceniu czasu blokowania wątków głównych.

Ta korelacja w połączeniu z obiekcjami wydawców firmy Taboola dotyczącymi dużej wartości TBT skłoniła Taboola do skupienia się na zminimalizowaniu udziału w tym wskaźniku.

Zrzut ekranu z kontroli Lighthouse dotyczące zablokowania czasu w wątku głównym. Wątek główny został łącznie zablokowany przez kilka skryptów przez 2630 milisekund, a kod JavaScript firmy zewnętrznej przyczynił się do tego 712 milisekund. Skrypt Release.js firmy Taboola odpowiada za większość czasu blokowania reklam innych firm (691 milisekund).
W starym mechanizmie Taboola skrypty takie jak RELEASE.js blokują wątek główny na 691 milisekund.

Wykorzystując TBT jako wskaźnik INP, Taboola zaczęła monitorować i optymalizować czas wykonywania JavaScriptu, aby ograniczyć swój potencjalny wpływ na podstawowe wskaźniki internetowe. Oto zaczęło się od:

  • Zidentyfikuj i zoptymalizuj problematyczne skrypty w terenie przy użyciu interfejsu Long Tasks API.
  • Szacowanie udziału TBT za pomocą PageSpeed Insights API w celu oceny od 10 000 do 15 000 adresów URL dziennie.

Firma Taboola zauważyła jednak, że analiza TBT za pomocą tych narzędzi niesie ze sobą pewne ograniczenia:

  • Interfejs Long Tasks API nie może przypisać zadania do domeny źródłowej ani konkretnego skryptu, co utrudnia identyfikację źródeł długich zadań.
  • Interfejs Long Tasks API identyfikuje tylko długie zadania, a nie kombinację zadań i zmian układu, które mogą powodować opóźnienia renderowania.

Aby sprostać tym wyzwaniom, firma Taboola dołączyła do testów origin interfejsu Long Animation Frames (LoAF) API, aby lepiej zrozumieć ich rzeczywisty wpływ na czas reakcji użytkowników na dane wejściowe. Wersje próbne origin zapewniają dostęp do nowych lub eksperymentalnych funkcji, dzięki czemu deweloperzy mogą testować nowe funkcje, które użytkownicy mogą wypróbować przez ograniczony czas.

Trzeba podkreślić, że najtrudniejszym aspektem tego wyzwania była poprawa wartości INP bez obniżania wskaźnika KPI Google Ads(kluczowego wskaźnika wydajności) i powodu opóźnień w zasobach wydawców.

Wykorzystanie LoAF do oceny wpływu INP

Długa ramka animacji pojawia się, gdy aktualizacja renderowania jest opóźniona o ponad 50 milisekund. Dzięki zidentyfikowaniu przyczyn powolnych aktualizacji interfejsu użytkownika (zamiast samych długich zadań) firma Taboola była w stanie przeanalizować jej wpływ na czas reagowania stron w tym polu. Obserwacja LoAF umożliwiła Taboola:

  1. Przypisz wpisy do konkretnych zadań Taboola.
  2. Obserwuj problemy z wydajnością funkcji przed wdrożeniem ich w środowisku produkcyjnym.
  3. Gromadzenie zagregowanych danych na potrzeby porównywania różnych wersji kodu w testach A/B i generowania raportów z kluczowymi wskaźnikami sukcesu.

Poniższy uproszczona wersja kodu JavaScript jest używana w środowisku produkcyjnym do zbierania danych LoAF w celu wyizolowania wpływu Tabooli.

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 });
  • Zastosowanie funkcji loafEntryAnalysis pozwoliło Taboola zidentyfikować wpisy, w których jest ona głównym współtwórcą.
  • Taboola jest uznawana za główny współtwórca, jeśli ponad połowa łącznego czasu trwania skryptu jest spowodowana przez Taboola lub gdy działanie skryptu Taboola trwa dłużej niż 50 milisekund.
  • Wartość firstUIEventTimeStamp jest generowana, jeśli interakcja użytkownika jest opóźniona z powodu długiej ramki animacji. Najdłuższy czas trwania blokowania jest uznawany za ogólny wynik INP. Możemy też określić, kiedy Taboola uruchomiła funkcję firstUIEventTimeStamp, aby obliczyć wynik INP Taboola.

Dane zebrane za pomocą LoAF pomogły firmie Taboola utworzyć poniższą tabelę atrybucji, która wskazuje obszary, w których można wykorzystać możliwości generowania zysków.

Skrypt Czas trwania (milisekundy)
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
Wpisy skryptu LoAF przechwycone przez Taboola RUM

TRECS Engine: nowa strategia zwiększania zysku

Firma Taboola nie tylko wykorzystała LoAF do lepszego zrozumienia możliwości optymalizacji skryptów, ale też przeprojektowała cały swój mechanizm renderowania, aby znacząco zminimalizować czas wykonywania i blokowania JavaScriptu.

TRECS (Taboola Recommendations Extensible Client Service) utrzymuje renderowanie po stronie klienta i aktualny kod JavaScript wydawcy, zmniejszając jednocześnie liczbę i rozmiar wymaganych plików wymaganych do wczytywania rekomendacji Taboola.

Po zidentyfikowaniu zadań blokujących renderowanie za pomocą LoAF „Faktor wydajności” może rozbić te zadania przed przejściem do wątku głównego za pomocą narzędzia scheduler.postTask(). Taki projekt umożliwia jak najszybsze wykonywanie najważniejszych zadań z punktu widzenia użytkownika – takich jak aktualizacje renderowania – niezależnie od istniejących zadań, które mogą zajmować wątek główny.

Oto fragment kodu JS uruchamiającego zadania „Performance Fader” (poprawka wydajności):

/**
* 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);
}

Funkcja sendTaskToFader:

  • Korzysta z metody runAsPostTask, która używa metody scheduler.postTask() w tle (jeśli interfejs API jest dostępny) lub zwraca wartość setTimeout.
  • Ta funkcja umieszcza wywołania funkcji w sekcjach kodu, które powodują długie klatki animacji i wartości INP. Dzieli te sekcje kodu na krótsze zadania, co zmniejsza wartość INP.

Dane biznesowe

Dzięki LoAF firma Taboola mogła lepiej zrozumieć swój wpływ na INP. Wskazano również możliwości optymalizacji skryptów, które można wykorzystać w ramach nowego silnika TRECS.

Aby określić wpływ TRECS i funkcji Fadera wydajności, firma Taboola przeprowadziła test A/B, który mierzy wartość INP w dotychczasowej wyszukiwarce. Żaden skrypt nie wpływał na panel partnerów wydawców.

Tabela poniżej przedstawia wyniki INP (w milisekundach) na 75 centylu wśród 4 anonimowych wydawców w sieci Taboola.

Wydawcy INP z TRECS + wyciszaniem wydajności INP z dotychczasową wyszukiwarką Spadek INP (%)
Wydawca A 48 75 36%
Wydawca B 153 163 6%
Wydawca C 92 135 33%
Wydawca D 37 52 29%

Na szczęście włączenie TRECS i zmniejszenia wydajności w panelu testowym nie miało negatywnego wpływu na dane biznesowe, takie jak współczynnik klikalności reklamy i przychód z 1000 wyświetleń (RPM). Ta korzystna poprawa wskaźnika INP nie wykazała oczekiwanych negatywnych wyników wskaźników KPI Google Ads, dlatego Taboola będzie stopniowo poprawiać postrzeganie swoich usług przez wydawców.

Kolejne uruchomienie narzędzia Lighthouse, które zostało użyte na tym samym kliencie, wykazało znaczącą poprawę czasu blokowania wątków głównych przez Taboola podczas korzystania z nowego silnika.

Zrzut ekranu z kontroli Lighthouse dotyczące zablokowania czasu w wątku głównym po zastosowaniu nowych silników TRECS i Performance Fader w celu skrócenia czasu blokowania wątku głównego. Czas kontroli został skrócony do zaledwie 206 milisekund (w porównaniu do 712 milisekund przed wprowadzeniem optymalizacji).
Nowy mechanizm firmy Taboola pomógł skryptom takim jak RELEASE.js zredukować TBT o 485 ms (-70%).

To pokazuje, że wykorzystanie LoAF do identyfikowania przyczyn INP i wdrożenie kolejnych technik generowania zysków za pomocą suwaka wydajności umożliwia partnerom firmy Taboola osiągnięcie maksymalnego sukcesu w zakresie skuteczności reklam i stron.

Podsumowanie

Optymalizacja INP to złożony proces, zwłaszcza gdy w witrynach partnerów używane są skrypty innych firm. Zanim rozpocznie się optymalizacja, przypisanie INP do konkretnych skryptów eliminuje wszelkie domysły i potencjalne szkody w innych danych dotyczących wydajności witryny. Interfejs LoAF API okazał się cennym narzędziem do identyfikowania i rozwiązywania problemów z INP, zwłaszcza w przypadku umieszczonych na stronie dostawców zewnętrznych. Umożliwia im to określenie konkretnych możliwości poprawy pakietów SDK i eliminuje zakłócenia działania innych technologii dostępnych na stronie.

W połączeniu z dobrą strategią zysku, np. z zastosowaniem algorytmu scheduler.postTask(), LoAF może pomóc w obserwacji i zrozumieniu przyczyn niskiej responsywności strony, co z kolei dostarcza informacji potrzebnych do poprawy wartości INP witryny.

Specjalne podziękowania dla Gilberto Cocchiego, Noama Rosenthala i Ricka Viscomiego z Google oraz Dedi Hakaka, Anata Dagana i Omri Ariava z zespołu ds. inżynierii i produktu firmy Taboola za wkład w te działania.