Jak firma Trendyol zmniejszyła wartość INP o 50%, uzyskując wzrost współczynnika klikalności o 1%

To studium przypadku opisuje krok po kroku przepływ pracy debugowania i ulepszania wartości INP w React, który jest używany przez firmę Trendyol przy użyciu narzędzi Google, takich jak PageSpeed Insights (PSI), Chrome DevTools i scheduler.yield API.

Dwie kluczowe części każdej witryny e-commerce to strona produktu (PLP) i strona ze szczegółami produktu (PDP). Ruch e-commerce pochodzi często ze stron z listą produktów, czy to przez kampanie e-mailowe, media społecznościowe, czy reklamy. Dlatego tak ważne jest, aby proces PLP był starannie zaprojektowany tak, aby skrócić czas potrzebny na dokonanie zakupu. Priorytetem jest zapewnienie użytkownikom wysokiej jakości. Publikacje z badaniami, takie jak Milliseconds Make Millions, ujawniły już znaczący wpływ szybkości działania stron internetowych na gotowość konsumentów do wydawania pieniędzy i nawiązywania interakcji z markami online.

Trendyol to platforma e-commerce, która ma około 30 milionów klientów i 240 tys. sprzedawców. Dzięki temu zostałamy pierwszą firmą w Turcji wartą ponad 10 miliardów dolarów i jedną z czołowych platform e-commerce na świecie.

Aby osiągnąć cel polegający na zapewnieniu jak najlepszej jakości wrażeń użytkowników na dużą skalę przy jednoczesnym zachowaniu elastyczności treści i działaniu ze starszą wersją React, firma Trendyol skupiła się na interakcji do kolejnego wyrenderowania (INP) jako kluczowym wskaźniku do ulepszenia. To studium przypadku opisuje proces ulepszania INP w PLP przez Trendyol, który zaowocował obniżeniem INP o 50%wzrostem o 1% w przypadku danych biznesowych dotyczących wyników wyszukiwania.

Proces Trendyol dotyczący dochodzeń w zakresie INP

INP mierzy responsywność witryny na dane wejściowe użytkownika. Dobry INP wskazuje, że przeglądarka może szybko i bezbłędnie reagować na wszystkie dane wejściowe użytkownika oraz odświeżać stronę, co jest kluczowym elementem zapewniającym dobre wrażenia użytkowników.

Droga firmy Trendyol do ulepszenia INP w swoim programie PLP rozpoczęła się od dokładnej analizy wrażeń użytkowników przed wprowadzeniem jakichkolwiek ulepszeń. Na podstawie raportu PSI rzeczywiste INP w przypadku PLP na urządzeniach mobilnych wynosi 963 milisekund, jak pokazano na następnym rysunku.

INP Trendyol według odczytu CrUX w PageSpeed Insights. 5 września 2023 r. średni czas wczytywania strony w przypadku Trendyol wynosił 963 ms, co mieści się w zakresie „zły”.
INP Trendyol na dzień 5 września 2023 r. z PSI.

Aby zapewnić dobrą responsywność, właściciele witryn powinni dążyć do wartości INP poniżej lub 200 milisekund, co oznacza, że w tym okresie wartość INP firmy Trendyol znajdowała się w „niskim” zakresie.

Na szczęście PSI zawiera zarówno dane z pól stron uwzględnionych w Raporcie na temat użytkowania Chrome (CrUX), jak i szczegółowe dane diagnostyczne z laboratorium. Analiza czasu wykonywania kodu JavaScriptu w Lighthouse na podstawie danych z testów laboratoryjnych sugerowała, że skrypt search-result-v2 zajmował główny wątek dłużej niż inne skrypty na stronie.

Wyświetlanie źródeł długich zadań w Lighthouse w przypadku witryny Trendyol. Jednym z głównych źródeł długich zadań jest skrypt obsługujący wyniki wyszukiwania w narzędziu PLP firmy Trendyol.
Czas wykonywania kodu JavaScript w witrynie Trendyol z audyt Lighthouse z 5 września 2023 r. z PSI.

Aby zidentyfikować wąskie gardła w rzeczywistych warunkach, użyliśmy panelu wydajności w narzędziach deweloperskich Chrome do rozwiązania problemów z PLP i znalezienia ich źródła. Emulowanie wydajności na urządzeniach mobilnych przy 4-krotnym spowolnieniu procesora w Narzędziach deweloperskich w Chrome ujawniło zadanie trwające 700–900 ms na głównym wątku. Jeśli główny wątek jest zajęty innymi zadaniami przez ponad 50 milisekund, może nie być w stanie odpowiednio szybko reagować na dane wejściowe użytkownika, co może pogorszyć wrażenia użytkownika.

Zrzut ekranu przedstawiający sesję profilowania wydajności w Narzędziach deweloperskich w Chrome w przypadku PLP Trendyol Przedstawione długie zadanie trwa 737, 6 milisekundy i jest częścią wywołania zwrotnego obserwacji intersekcji.
Narzędzie do profilowania wydajności długich zadań z potoku Trendyol w panelu wydajności w Narzędziach deweloperskich w Chrome.

Najdłuższe zadanie zostało spowodowane przez wywołanie zwrotne Intersection Observer API w skrypcie wyników wyszukiwania wewnątrz komponentu React. W tym momencie zaczęliśmy rozbijać długie zadanie na małe fragmenty, aby dać przeglądarce więcej możliwości reagowania na zadania o wyższym priorytecie, w tym na interakcje z użytkownikiem.

Okazuje się, że użycie operacji setState, która powoduje ponowne renderowanie Reacta w wywołaniu zwrotnym IntersectionObserver, wiąże się z wysokimi kosztami, co może być problematyczne na urządzeniach niskiej klasy, ponieważ zajmuje to zbyt dużo czasu w głównym wątku.

Jedną z metod, której deweloperzy używają do dzielenia zadań na mniejsze, jest setTimeout. Użyliśmy tej techniki, aby przełożyć wykonanie wywołania setState do osobnego zadania. Chociaż tag setTimeout umożliwia odroczenie wykonania kodu JavaScript, nie pozwala na kontrolowanie priorytetu. Z tego powodu dołączyliśmy do próby scheduler.yield, aby zapewnić kontynuację wykonywania skryptu po przekazaniu wątku głównemu:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

Dodanie tej metody generowania zysków do kodu PLP przyniosło poprawę wartości INP, ponieważ główne długie zadanie zostało podzielone na kilka mniejszych, dzięki czemu praca o wyższym priorytecie, np. interakcje użytkowników i późniejsze renderowanie, zostanie wykonana szybciej, niż byłoby to możliwe.

Zrzut ekranu przedstawiający sesję profilowania wydajności w Narzędziach deweloperskich w Chrome w przypadku PLP Trendyol Długie zadanie, które wcześniej trwało 737,6 ms, jest teraz podzielone na kilka krótszych zadań.
Zadanie podzielone na mniejsze.

Pamiętaj, że Trendyol używa ramy PuzzlJs do implementowania mikrofrontendu w architekturze React w wersji 16.9.0. Dzięki React 18 można osiągnąć tę samą skuteczność, ale z wielu powodów Trendyol nie może obecnie przejść na wyższą wersję.

Wyniki biznesowe

Aby sprawdzić wpływ wdrożenia ulepszenia INP, przeprowadziliśmy test A/B, aby zobaczyć, jak wpłynęło to na dane biznesowe. Ogólnie zmiany w PLP przyniosły znaczną poprawę, w tym zmniejszenie współczynnika INP o 50% oraz wzrost współczynnika klikalności ze strony z ofertą na stronę ze szczegółami produktu o 1% na każdą sesję użytkownika. Na poniższym rysunku widać, jak na przestrzeni czasu poprawiała się skuteczność INP w PLP:

Zrzut ekranu pokazujący 75-procentylowy INP Trendyol w ciągu 6 miesięcy. Pod koniec 6 miesięcy średni czas wczytywania strony w przypadku Trendyol zmniejszył się z prawie 1400 ms do prawie 650 ms.
75-procentowe poprawki INP w ciągu czasu.

Podsumowanie

Optymalizacja INP to złożony i powtarzalny proces, ale można go ułatwić dzięki przejrzystemu przepływowi pracy. Proste debugowanie i poprawianie wskaźnika INP witryny zależy od tego, czy gromadzisz własne dane pól. Jeśli nie, dobrym punktem wyjścia są PSI i Lighthouse. Gdy zidentyfikujesz strony z problemami, możesz użyć Narzędzi deweloperskich, aby dokładniej zbadać problemy i spróbować je odtworzyć.

Od czasu do czasu oddawanie wątku głównemu, aby dać przeglądarce więcej możliwości wykonania pilnych zadań, sprawi, że Twoja witryna będzie bardziej responsywna, a klienci będą mieli lepsze wrażenia. Nowsze interfejsy API do planowania, takie jak scheduler.yield(), ułatwiają to zadanie.

Specjalne podziękowania dla Jeremy’ego Wagnera, Barry’ego Pollarda i Housseina Djirdeh z Google oraz zespołu inżynierów Trendyol za ich wkład w realizację tego projektu.