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 strategii inteligentnego zysku umożliwiło firmie Taboola poprawę wyników wydawców responsywności witryny bez obniżania skuteczności reklam.

David Belford
David Belford

Interakcja z następnym wyrenderowaniem (INP) to wartość oceniająca responsywność witryny na dane wejściowe użytkownika. INP mierzy czas od momentu rozpoczęcia interakcji przez użytkownika – na przykład kliknięcia, dotknięcia lub pisania – do wizualnego potwierdzenia otrzymanego informacji. W marcu 2024 r. wskaźnik INP zastąpi opóźnienie przy pierwszym działaniu (FID) jako podstawowy wskaźnik internetowy w marcu 2024 r..

Taboola to najpopularniejsza na świecie platforma do odkrywania treści, która generuje co sekundę 500 tys. rekomendacji w otwartej sieci. Dzięki tym rekomendacjom 9000 wyjątkowych partnerów Taboola może zarabiać i angażować odbiorców. Wydawcy renderują rekomendacje na swoich stronach za pomocą JavaScriptu.

Skrypty JavaScript innych firm mogą wpływać na zdolność strony do szybkiego reagowania na dane wejściowe użytkownika, dlatego firma Taboola intensywnie pracuje nad zmniejszeniem rozmiaru plików JavaScript i czasu wykonywania działań. Aby zminimalizować wpływ na INP, firma Taboola przeprojektowała cały silnik renderowania i korzystała bezpośrednio z interfejsów API przeglądarki bez żadnych abstrakcji.

To studium przypadku przedstawia działania firmy Taboola nad udoskonalaniem INP przez wykorzystanie nowego interfejsu API Long Animation Frames (LoAF) do pomiaru jego wpływu na responsywność stron w terenie, a następnie na wdrożenie konkretnych optymalizacji, które poprawią wrażenia użytkowników.

TBT jako proxy INP

Całkowity czas blokowania (TBT) to dane oparte na laboratoriach, które identyfikują, gdzie wątek główny był zablokowany na wystarczająco długo, aby prawdopodobnie wpłynąć na responsywność stron. Duża ilość danych w polu, w których mierzy się czas reakcji (np. INP), może mieć wpływ na dane pól. Zbadanie przez Annie Sullivan korelacji między TBT i INP na urządzeniach mobilnych wykazało, że witryny z większym prawdopodobieństwem uzyskują dobre wyniki INP, gdy czas blokowania głównego wątku jest zminimalizowany.

Ta korelacja pomogła wydawcom Taboola obawy o dużą ilość czasu na dane, firma Taboola skupiła się na zminimalizowaniu swojego udziału w tym wskaźniku.

Zrzut ekranu z audytu Lighthouse dotyczącego zablokowanego czasu wątku głównego. Wątek główny był w sumie blokowany przez kilka skryptów przez 2630 milisekund, przy czym JavaScript innej firmy odpowiadał za to 712 milisekund. Za większość czasu blokowania reklam firm zewnętrznych (691 milisekund) odpowiada skrypt launch.js firmy Taboola.
W starym mechanizmie Tabooli skrypty takie jak RELEASE.js blokują wątek główny przez 691 milisekund.

Wykorzystując TBT jako wskaźnik pośredniczący dla INP, firma Taboola zaczęła monitorować i optymalizować czas wykonywania JavaScriptu, aby ograniczyć jego potencjalny wpływ na podstawowe wskaźniki internetowe. Zaczęli od wykonania tych czynności:

  • Zidentyfikować i zoptymalizować problematyczne skrypty w polu przy użyciu interfejsu Long Tasks API.
  • Szacowanie udziału w TBT przy użyciu interfejsu PageSpeed Insights API do oceny 10–15 tys. adresów URL dziennie.

Firma Taboola zauważyła jednak, że analizowanie 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 zmiany układu, które mogą powodować opóźnienia renderowania.

Aby stawić czoła tym wyzwaniom, firma Taboola dołączyła do testowania origin interfejsu Long Animation Frames (LoAF), aby lepiej zrozumieć jego rzeczywisty wpływ na responsywność danych wejściowych użytkownika. Wersje próbne origin dają dostęp do nowych lub eksperymentalnych funkcji, dzięki którym deweloperzy mogą testować nowe funkcje, które użytkownicy mogą wypróbować przez ograniczony czas.

Trzeba wyraźnie podkreślić, że najtrudniejszym aspektem tego wyzwania było pomyślne ulepszenie wartości INP bez negatywnego wpływu na KPI Google Ads(kluczowego wskaźnika wydajności) i opóźnienia w korzystaniu z zasobów naszych wydawców.

Używanie LoAF do oceny wpływu INP

Długa klatka animacji pojawia się, gdy aktualizacja renderowania jest opóźniona o więcej niż 50 milisekund. Dzięki zidentyfikowaniu przyczyn powolnych aktualizacji interfejsu użytkownika – zamiast samych długich zadań – firma Taboola była w stanie przeanalizować swój wpływ na czas reakcji stron w polu. Obserwacja LoAF pozwoliła Taboola:

  1. Przypisz wpisy do określonych zadań Taboola.
  2. Przyjrzyj się problemom z wydajnością konkretnych funkcji, zanim wdrożysz je w środowisku produkcyjnym.
  3. Zbieraj dane zbiorcze, by porównywać różne wersje kodu w testach A/B, i twórz raporty o kluczowych wskaźnikach sukcesu.

Poniższy kod JavaScript to uproszczona wersja wykorzystywana w środowisku produkcyjnym do zbierania danych o loAF w celu wyodrębnienia wpływu aplikacji 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 });
  • Dzięki funkcji loafEntryAnalysis firma Taboola mogła zidentyfikować wpisy, w przypadku których jest najbardziej istotnym czynnikiem.
  • Uznaje się, że aplikacja Taboola jest głównym współtwórcą, jeśli ponad połowa łącznego czasu trwania skryptu jest spowodowana przez aplikację Taboola lub jeśli uruchomienie 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 klatki animacji. Najdłuższy czas blokowania jest uznawany za ogólny wynik INP. Możemy też ustalić, kiedy Taboola wywołała funkcję firstUIEventTimeStamp, aby obliczyć wynik INP Taboola.

Dane zebrane za pomocą LoAF pomogły firmie Taboola utworzyć następującą tabelę atrybucji, która identyfikuje obszary, w których można zastosować dochodowe możliwości.

.
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 zysku

Oprócz wykorzystania LoAF do lepszego zrozumienia możliwości optymalizacji skryptów Taboola przeprojektowała cały mechanizm renderowania, aby znacznie zminimalizować czas wykonywania i blokowania obsługi JavaScriptu.

TRECS (Taboola Recommendations Extensible Client Service) obsługuje renderowanie po stronie klienta i aktualny kod JS wydawcy, jednocześnie zmniejszając liczbę i rozmiar obowiązkowych plików wymaganych do wczytania rekomendacji Taboola.

Gdy zadania blokujące renderowanie zostaną zidentyfikowane za pomocą LoAF, funkcja „Performance Fader” może je podzielić, zanim przejdziesz do wątku głównego za pomocą narzędzia scheduler.postTask(). Taka konstrukcja daje pewność, że kluczowe działania, przed którymi mierzą się użytkownicy, takie jak aktualizacje renderowania, zostaną jak najszybciej wykonane, niezależnie od istniejących zadań, które zajmują główny wątek.

Oto fragment kodu JS narzędzia Performance Fader mechanizm uruchamiania zadań:

/**
* 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:

  • Używane jest runAsPostTask, które korzysta z metody scheduler.postTask() wbudowanej w środowisko (jeśli interfejs API jest dostępny) lub wraca do wartości 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ć jej wpływ na INP. Narzędzie wskazało też możliwości optymalizacji skryptów, które można wykorzystać w ramach nowego silnika TRECS.

Aby określić wpływ TRECS i Performance Fader, firma Taboola przeprowadziła test A/B, który mierzył wartość INP w obecnym silniku i nie uzyskał żadnego skryptu z panelu partnerów wydawców.

Poniższa tabela przedstawia w milisekundach wyniki wartości INP dla 75 centyla z 4 anonimowych wydawców w sieci Taboola.

Wydawcy INP z TRECS + Performance Fader INP z istniejącą 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 suwaka skuteczności w panelu testowym nie wpłynęło negatywnie na dane biznesowe, takie jak współczynnik klikalności reklamy i przychody na 1000 wyświetleń (RPM). Pozytywny wzrost wskaźnika INP bez oczekiwanych negatywnych wyników w wskaźnikach KPI Google Ads sprawia, że Taboola stopniowo poprawia wyniki punktu widzenia na temat jego produktu.

Ponowne uruchomienie w Lighthouse tego samego klienta wcześniej podkreślało istotną poprawę czasu blokowania wątków głównych przez firmę Taboola w przypadku korzystania z nowego silnika.

Zrzut ekranu z audytu Lighthouse dotyczącego zablokowanego czasu wątku głównego po zastosowaniu nowych mechanizmów TRECS i Performance Fader w celu skrócenia czasu blokowania wątków głównych. Czas kontroli został skrócony do 206 milisekund, podczas gdy przed wprowadzeniem optymalizacji było ich 712.
Nowy mechanizm Taboola pomógł skryptom takim jak RELEASE.js ograniczyć czas TBT o 485 ms (-70%).

To pokazuje, że wykorzystanie LoAF do identyfikowania przyczyn INP i stosowania kolejnych technik generowania zysków za pomocą narzędzia Performance Fader pozwala partnerom firmy Taboola osiągnąć maksymalny sukces w zakresie skuteczności reklam i stron.

Podsumowanie

Optymalizacja INP to skomplikowany proces, zwłaszcza gdy w witrynach partnerskich używane są skrypty innych firm. Przed rozpoczęciem optymalizacji przypisywanie wartości INP do konkretnych skryptów eliminuje wszelkie domysły i potencjalne uszkodzenia innych danych dotyczących wydajności witryny.Interfejs LoAF API jest przydatnym narzędziem do identyfikowania i rozwiązywania problemów z INP, zwłaszcza w przypadku osadzonych firm zewnętrznych, ponieważ umożliwia wskazanie konkretnych możliwości ulepszenia pakietu SDK, a jednocześnie eliminuje zakłócenia z innych technologii dostępnych na stronie.

W połączeniu z dobrą strategią zysku, np. z zasadą scheduler.postTask(), LoAF może ułatwić obserwację i zrozumienie przyczyn słabego reagowania stron, co z kolei dostarcza informacji potrzebnych do poprawy wskaźnika INP witryny.

Specjalne podziękowania dla Gilberto Cocchi, Noama Rosenthala i Ricka Viscomiego z Google oraz Dedi Hakak, Anata Dagana i Omriego Ariava z zespołu inżynierii i produktu firmy Taboola za ich wkład w tę pracę.