Rozwiązywanie problemów z CLS w witrynie e-commerce opartej na Next.js (studium przypadku)

Opublikowany: 2022-03-10
Krótkie podsumowanie ↬ Zbiorcza zmiana układu jest jedną z najtrudniejszych sieci kluczowych do debugowania. W tym artykule omawiamy różne narzędzia, aby zbadać CLS, kiedy ich używać (a kiedy nie) oraz rozwiązania niektórych problemów z CLS, z którymi mieliśmy do czynienia w naszej witrynie e-commerce opartej na Next.js.

Fairprice to jeden z największych internetowych sklepów spożywczych w Singapurze. Nieustannie poszukujemy obszarów możliwości poprawy doświadczenia użytkownika podczas zakupów online. Wydajność jest jednym z podstawowych aspektów zapewniających naszym użytkownikom przyjemne wrażenia z użytkowania, niezależnie od ich urządzeń lub połączenia sieciowego.

Istnieje wiele kluczowych wskaźników wydajności (KPI), które mierzą różne punkty w cyklu życia strony internetowej (takie jak TTFB, domInteractive i onload ), ale te metryki nie odzwierciedlają sposobu, w jaki użytkownik końcowy odbiera stronę.

Chcieliśmy wykorzystać kilka wskaźników KPI, które ściśle odpowiadają rzeczywistym doświadczeniom użytkowników końcowych, więc wiemy, że jeśli którykolwiek z tych wskaźników KPI nie działa dobrze, będzie to miało bezpośredni wpływ na wrażenia użytkownika końcowego. Odkryliśmy, że metryki wydajności zorientowane na użytkownika idealnie nadają się do tego celu.

Istnieje wiele metryk wydajności zorientowanych na użytkownika, które mierzą różne punkty w cyklu życia strony, takie jak FCP, LCP, FID, CLS i tak dalej. W tym studium przypadku skupimy się głównie na CLS.

CLS mierzy łączny wynik wszystkich nieoczekiwanych zmian układu między momentem rozpoczęcia ładowania strony a jej wyładowaniem.

W związku z tym niska wartość CLS dla strony gwarantuje, że nie ma losowych przesunięć układu, powodujących frustrację użytkowników. Barry Pollard napisał doskonały szczegółowy artykuł na temat CLS.

Jak odkryliśmy problem CLS na naszej stronie produktu?

Używamy Lighthouse i WebPagetest jako naszych syntetycznych narzędzi testujących wydajność do pomiaru CLS. Korzystamy również z biblioteki web-vitals do mierzenia CLS dla prawdziwych użytkowników. Poza tym sprawdzamy sekcję Google Search Console Core Web Vitals Report, aby dowiedzieć się o wszelkich potencjalnych problemach z CLS na naszych stronach. Podczas przeglądania sekcji raportu odkryliśmy, że wiele adresów URL ze strony szczegółów produktu ma wartość CLS większą niż 0,1 , co sugeruje, że ma tam miejsce poważne zdarzenie zmiany układu.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Debugowanie problemu CLS przy użyciu różnych narzędzi

Teraz, gdy wiemy, że na stronie szczegółów produktu występuje problem z CLS, następnym krokiem było zidentyfikowanie, który element go powoduje. Na początku zdecydowaliśmy się przeprowadzić testy przy użyciu syntetycznych narzędzi testowych.

Więc uruchomiliśmy latarnię morską, aby sprawdzić, czy może znaleźć jakikolwiek element, który może wywołać poważną zmianę układu, zgłosiła CLS do 0,004, która jest dość niska.

CLS to 0,004
CLS wykazał niski wynik CLS wynoszący .004 . (duży podgląd)

Strona raportu Lighthouse zawiera sekcję diagnostyczną. To również nie wykazało żadnego elementu powodującego wysoką wartość CLS.

Strona raportu o latarni morskiej
Podgląd strony raportu z wynikami wkładu CLS. (duży podgląd)

Następnie uruchomiliśmy WebpageTest i postanowiliśmy sprawdzić widok taśmy filmowej:

widok taśmy filmowej
Widok taśmy filmowej pokazuje każdą klatkę, która ma wizualną zmianę i przesunięcie układu, żółtą przerywaną linią. (duży podgląd)

Ta funkcja jest dla nas bardzo pomocna, ponieważ możemy dowiedzieć się, który element w jakim momencie spowodował przesunięcie układu. Ale kiedy przeprowadzamy test, aby sprawdzić, czy jakiekolwiek zmiany w układzie są podświetlone, nic nie przyczyniło się do ogromnego LCS:

przetestuj, który element w jakim momencie spowodował zmianę układu
Możesz dowiedzieć się, czy nastąpiły jakiekolwiek zmiany w układzie, po prostu rzucając okiem na ramki. (duży podgląd)

Dziwactwo z CLS polega na tym, że rejestruje indywidualne wyniki zmiany układu podczas całego życia strony i dodaje je.

Uwaga : sposób pomiaru CLS został zmieniony od czerwca 2021 r.

Ponieważ Lighthouse i WebpageTest nie mogły wykryć żadnego elementu, który wywołał poważną zmianę układu, co oznacza, że ​​nastąpiło to po początkowym załadowaniu strony, prawdopodobnie z powodu jakiegoś działania użytkownika. Zdecydowaliśmy się więc użyć rozszerzenia Web Vitals Google Chrome, ponieważ może ono rejestrować CLS na stronie, gdy użytkownik wchodzi z nią w interakcję. Po wykonaniu różnych czynności stwierdziliśmy, że wynik przesunięcia układu zwiększa się, gdy użytkownik korzysta z funkcji powiększenia obrazu.

Aby zweryfikować krzyżowo, czy przesunięcie układu występuje, gdy na obrazie znajduje się kursor myszy, użyliśmy poniższego fragmentu kodu z https://web.dev/cls/, który dodaje console.log , gdy nastąpi przesunięcie układu:

 let cls = 0; new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (!entry.hadRecentInput) { cls += entry.value; console.log('Current CLS value:', cls, entry); } }}).observe({type: 'layout-shift', buffered: true});

Podczas dalszego dochodzenia odkryliśmy, że ASDA boryka się z podobnym problemem i podniosło go w przypadku chromu.

Główna przyczyna

Na stronie szczegółów produktu użytkownicy mogą najechać myszą na obraz produktu, aby wyświetlić powiększoną część obrazu obok rzeczywistego obrazu produktu, ponieważ ten film pokazuje dokładnie to, o czym mówimy.

Funkcja powiększania obrazu pomaga naszym użytkownikom uzyskać wygląd produktu, a także upewnić się, że jest to właściwy wariant produktu, który chcą kupić.

Do zbudowania tej funkcji powiększania obrazu użyliśmy biblioteki react-image zoom .

Biblioteki Image Magnify mają zazwyczaj soczewkę (kwadrat, który porusza się, gdy mysz porusza się w obrębie obrazu). Ponieważ ten obiektyw zmienia swoją górną i lewą pozycję wraz z ruchem myszy, jest wykrywany jako zmiana układu wyzwalająca CLS. Sprawdziliśmy stronę biblioteki, a także inne podobne biblioteki React ( react-image-magnify , react-image-zoom , react-image-magnifiers ) i stwierdziliśmy, że wszystkie z nich cierpią na ten sam problem z CLS.

Jak to naprawiliśmy?

Zauważyliśmy, że react-image-zoom używa biblioteki js-image-zoom . Musieliśmy więc zmodyfikować bibliotekę js-image zoom , aby naprawić ten problem.

Rozwiązanie jest dość proste. Gdy mysz porusza się po obrazie produktu, element soczewki obrazu porusza się, zmieniając jego lewą i górną pozycję. Aby rozwiązać ten problem, użyliśmy transform translate , który przenosi element na nową warstwę, tzn. każdy ruch, który ma miejsce na tej nowej warstwie, nie powoduje już przesunięcia układu:

zarządzanie ruchem soczewki za pomocą transform translate
(duży podgląd)

Stworzyłem również PR do oryginalnego repozytorium, aby inni programiści korzystający z tej biblioteki mogli pozbyć się problemu z CLS.

tworzenie PR do oryginalnego repozytorium
PR stworzony, aby pomóc pozbyć się problemu CLS. (duży podgląd)

Wpływ zmiany

Po wdrożeniu kodu do produkcji naprawiono CLS na stronie szczegółów produktu, a liczba stron dotkniętych CLS została zmniejszona o 98%:

grafika, która pokazuje wpływ zmiany.
transform ma przewagę wydajności nad manipulacją pozycją za pomocą lewej i górnej części. (duży podgląd)

Ponieważ użyliśmy transform , pomogło to również zwiększyć płynność obrazu dla użytkowników.

Uwaga : Paul Irish napisał doskonały artykuł na ten temat.

Inne kluczowe zmiany, które wprowadziliśmy dla CLS

Na wielu stronach naszej witryny internetowej pojawiły się również inne problemy, które przyczyniają się do rozwoju CLS. Przyjrzyjmy się tym elementom i komponentom i zobaczmy, jak staraliśmy się złagodzić wynikające z nich zmiany w układzie.

  • Czcionki internetowe:
    Zauważyliśmy, że późne ładowanie czcionek powoduje frustrację użytkowników, ponieważ zawartość miga, a także powoduje pewne przesunięcia układu. Aby to zminimalizować wprowadziliśmy kilka zmian:

    • Hostowaliśmy czcionki na własnym serwerze zamiast ładowania z CDN innej firmy.
    • Wstępnie ładujemy czcionki.
    • Używamy opcjonalnego wyświetlania czcionek.
  • Zdjęcia:
    Brak wartości wysokości lub szerokości w obrazie powoduje przesunięcie elementu za obrazem po załadowaniu obrazu. To staje się głównym czynnikiem przyczyniającym się do CLS. Ponieważ używamy Next.js, skorzystaliśmy z wbudowanego komponentu obrazu o nazwie next/images . Ten składnik zawiera kilka najlepszych praktyk związanych z obrazami. Jest on oparty na tagu HTML <img> i może pomóc ulepszyć LCP i CLS. Gorąco polecam przeczytanie tego RFC, aby poznać kluczowe funkcje i zalety korzystania z niego.

  • Nieskończone przewijania:
    W naszej witrynie strony z listą produktów można przewijać w nieskończoność. Tak więc początkowo, gdy użytkownicy przewiną do dołu strony, widzą stopkę przez ułamek sekundy przed załadowaniem następnego zestawu danych, powoduje to zmiany układu. Aby rozwiązać ten problem, wykonaliśmy kilka kroków:

    • Wywołujemy API w celu załadowania danych jeszcze zanim użytkownik dotrze do absolutnego końca listy.
    • Zarezerwowaliśmy wystarczająco dużo miejsca na stan załadunku i pokazujemy szkielety produktów podczas stanu załadunku. Więc teraz, gdy użytkownik przewija, nie widzi stopki przez ułamek sekundy, gdy produkty są ładowane.

Addy Osmani napisał szczegółowy artykuł na temat tego podejścia, który gorąco polecam.

Kluczowe dania na wynos

  • Chociaż Lighthouse i WebpageTest pomagają wykrywać problemy z wydajnością występujące do momentu załadowania strony, nie mogą wykryć problemów z wydajnością po załadowaniu strony.
  • Rozszerzenia Web Vitals mogą wykrywać zmiany CLS wywołane interakcjami użytkownika, więc jeśli strona ma wysoką wartość CLS, ale Lighthouse lub WebpageTest zgłasza niski CLS, rozszerzenie Web Vitals może pomóc w ustaleniu problemu.
  • Dane Google Search Console są oparte na danych rzeczywistych użytkowników, dzięki czemu mogą również wskazywać na potencjalne problemy z wydajnością występujące w dowolnym momencie cyklu życia strony. Po wykryciu i naprawieniu problemu ponowne sprawdzenie sekcji raportu może pomóc w zweryfikowaniu skuteczności poprawki wydajności. Zmiany zostaną odzwierciedlone w sekcji raportu wskaźników internetowych w ciągu kilku dni.

Końcowe przemyślenia

Chociaż problemy z CLS są stosunkowo trudniejsze do debugowania, użycie kombinacji różnych narzędzi do czasu załadowania strony (Lighthouse, WebPageTest) i rozszerzenia Web Vitals (po załadowaniu strony) może pomóc nam zidentyfikować problem. Jest to również jedna z metryk, która jest aktywnie rozwijana w celu uwzględnienia szerokiego zakresu scenariuszy, a to oznacza, że ​​sposób jej pomiaru ulegnie zmianie w przyszłości. Śledzimy https://web.dev/evolving-cls/, aby dowiedzieć się o wszelkich nadchodzących zmianach.

Jeśli chodzi o nas, nieustannie pracujemy nad ulepszaniem innych kluczowych wskaźników internetowych. Niedawno wdrożyliśmy responsywne wstępne ładowanie obrazów i zaczęliśmy udostępniać obrazy w formacie WebP, co pomogło nam zredukować 75% ładunku obrazu, zmniejszyć LCP o 62%, a indeks szybkości o 24%. Możesz przeczytać więcej szczegółów na temat optymalizacji w celu poprawy LCP i wskaźnika szybkości lub śledzić nasz blog inżynierski, aby dowiedzieć się o innych ekscytujących pracach, które wykonujemy.

Chcielibyśmy podziękować Alexowi Castle za pomoc w debugowaniu problemu z CLS na stronie produktu i rozwiązanie dziwactw w next/images .