Cumulative Layout Shift (CLS)

Obsługa przeglądarek

  • Chrome: 77.
  • Edge: 79.
  • Firefox: nieobsługiwane.
  • Safari: nieobsługiwane.

Źródło

Nieoczekiwane zmiany układu mogą zakłócać wrażenia użytkownika na wiele sposobów, np. powodować utratę miejsca podczas czytania, jeśli tekst nagle się przesunie, lub prowadzić do kliknięcia niewłaściwego linku lub przycisku. W niektórych przypadkach może to spowodować poważne uszkodzenia.

Nagłe przesunięcie układu powoduje, że użytkownik potwierdza duże zamówienie, które chciał anulować.

Nieoczekiwane przemieszczanie się treści na stronie zwykle występuje, gdy zasoby są wczytywane asynchronicznie lub elementy DOM są dynamicznie dodawane do strony przed istniejącymi treściami. Przyczyną przesunięć układu mogą być obrazy lub filmy o nieznanych wymiarach, czcionki renderowane w większym lub mniejszym rozmiarze niż ich początkowe ustawienie domyślne albo reklamy lub widżety innych firm, które dynamicznie zmieniają rozmiar.

Problem ten pogłębiają różnice między tym, jak witryna działa podczas tworzenia, a jak widzą ją użytkownicy. Na przykład:

  • Treści spersonalizowane lub pochodzące od innych firm często zachowują się inaczej w trakcie tworzenia i w produkcji.
  • Obrazy testowe są często już w pamięci podręcznej przeglądarki dewelopera, ale wczytują się dłużej dla użytkownika końcowego.
  • Wywołania interfejsu API wykonywane lokalnie są często tak szybkie, że niezauważalne opóźnienia w rozwoju mogą stać się znaczące w produkcji.

Dane Cumulative Layout Shift (CLS) pomagają rozwiązać ten problem, ponieważ pozwalają mierzyć, jak często występuje on u prawdziwych użytkowników.

Co to jest CLS?

CLS to pomiar największej serii wartości przesunięcia układu dla każdego nieoczekiwanego przesunięcia układu, do którego doszło w całym okresie działania strony.

Przesunięcie układu występuje za każdym razem, gdy widoczny element zmienia swoją pozycję z jednej renderowanej klatki na kolejną. Szczegółowe informacje o sposobie obliczania poszczególnych wyników przesunięcia układu znajdziesz w dalszej części tego przewodnika.

Seria zmian układu, zwana oknem sesji, to sytuacja, w której co najmniej 1 pojedyncza zmiana układu następuje po sobie z przedziałem krótszym niż 1 sekunda i nie dłuższym niż 5 sekund.

Najdłuższa seria to okno sesji z maksymalnym skumulowanym wynikiem wszystkich przesunięć układu w tym oknie.

Przykład okien sesji. Niebieskie paski wskazują wyniki poszczególnych przesunięć układu.

Jaki wynik CLS jest dobry?

Aby wygodnie korzystać z witryny, użytkownicy powinni mieć wynik CLS wynoszący 0,1 lub mniej. Aby mieć pewność, że osiągasz ten cel w przypadku większości użytkowników, warto mierzyć 50. percentyl wczytywania stron podzielony na urządzenia mobilne i komputery.

Dobre wartości CLS to 0,1 lub mniej, złe wartości to więcej niż 0,25, a wszystkie wartości pośrednie wymagają poprawy.
Dobre wartości CLS wynoszą 0,1 lub mniej. Wartości złe są większe niż 0,25.

Więcej informacji o badaniach i metodologii, na których opierają się te zalecenia, znajdziesz w artykule Definiowanie progów podstawowych wskaźników internetowych.

Szczegóły przesunięć układu

Zmiany układu są definiowane przez interfejs API niestabilności układu, który w przypadku każdego elementu widocznego w widoku portu zmienia jego pozycję początkową (np. położenie w górę i w lewo w domyślnym trybie pisania) między 2 klatkami.layout-shift Takie elementy są uważane za niestabilne.

Pamiętaj, że zmiany układu występują tylko wtedy, gdy dotychczasowe elementy zmienią swoją pozycję początkową. Dodanie nowego elementu do DOM lub zmiana rozmiaru istniejącego elementu nie jest zmianą układu, o ile nie powoduje zmiany pozycji początkowej innych widocznych elementów.

Wynik przesunięcia układu

Aby obliczyć wynik przesunięcia układu, przeglądarka sprawdza rozmiar widocznego obszaru oraz ruch niestabilnych elementów w widocznym obszarze między 2 renderowanymi klatkami. Wynik przesunięcia układu jest iloczynem 2 miar tego przesunięcia: ułamka wpływuułamka odległości (obie zdefiniowane poniżej).

layout shift score = impact fraction * distance fraction

Frakcja wpływu

Ułamek wpływu mierzy, jak niestabilne elementy wpływają na obszar widoku między 2 klatkami.

Ułamek wpływu danej klatki to kombinacja widocznych obszarów wszystkich niestabilnych elementów w tej klatce i poprzedniej klatce jako ułamek całkowitej powierzchni widoku.

Przykład wpływu ułamka z 1 niestabilnym elementem
Jeśli element zmienia pozycję, zarówno jego poprzednia, jak i obecna pozycja przyczyniają się do jego wartości współczynnika wpływu.

Na poprzednim obrazie widać element, który zajmuje połowę widoku w ramach jednej klatki. Następnie w następnej klatce element przesuwa się w dół o 25% wysokości widocznego obszaru. Czerwony, kropkowany prostokąt wskazuje obszar widoczny elementu w obu ramkach, który w tym przypadku wynosi 75% całkowitego widoku, więc jego współczynnik wpływu wynosi 0.75.

Ułamek odległości

Druga część równania wyniku przesunięcia układu mierzy odległość, jaką niestabilne elementy przemieściły się względem widocznego obszaru. Ułamek odległości to największa odległość pozioma lub pionu, jaką niestabilny element przebył w ramce, podzielona przez największy wymiar widocznego obszaru (szerokość lub wysokość, zależnie od tego, który z tych wymiarów jest większy).

Przykład ułamka odległości z jednym niestabilnym elementem
Wartość odległości określa, jak daleko element się przesunął w widocznym obszarze.

W poprzednim przykładzie największy wymiar widocznego obszaru to wysokość, a niestabilny element przesunął się o 25% wysokości widocznego obszaru, co oznacza, że ułamek odległości wynosi 0,25.

W tym przykładzie ułamek wpływu wynosi 0.75, a ułamek odległości – 0.25, więc wynik przesunięcia układu to 0.75 * 0.25 = 0.1875.

Przykłady

Następujący przykład pokazuje, jak dodanie treści do istniejącego elementu wpływa na wynik przesunięcia układu:

Przykład zmiany układu z wieloma stabilnymi i niestabilnymi elementami
Dodanie przycisku u dołu szarego pola powoduje przesunięcie zielonego pola w dół i częściowe jego wyjście poza obszar widoczny.

W tym przykładzie rozmiar szarej ramki się zmienia, ale jej pozycja początkowa pozostaje taka sama, więc nie jest to element niestabilny.

Przycisk „Kliknij mnie!” nie znajdował się wcześniej w DOM, więc jego pozycja początkowa się nie zmieni.

Początkowa pozycja zielonego pola się zmienia, ale ponieważ zostało ono częściowo przeniesione poza obszar widoku, niewidoczny obszar nie jest brany pod uwagę przy obliczaniu udziału w skutku. Zbiór widocznych obszarów zielonego pola w obu kadrach (pokazany przez czerwony, kropkowany prostokąt) jest taki sam jak obszar zielonego pola w pierwszym kadrze – 50% widoku. Ułamek wpływu wynosi 0.5.

Ułamek odległości jest oznaczony fioletową strzałką. Zielone pole przesunęło się w dół o około 14% widocznego obszaru, więc ułamek odległości wynosi 0.14.

Wynik przesunięcia układu: 0.5 x 0.14 = 0.07.

Na przykładzie poniżej widać, jak wiele niestabilnych elementów wpływa na wskaźnik przesunięcia układu strony:

Przykład przesunięcia układu z elementami stabilnymi i _niestabilnymi_ oraz przycięciem obszaru widoku
Gdy na tej liście pojawi się więcej nazw, dotychczasowe nazwy przesuwają się, aby zachować kolejność alfabetyczną.

Na pierwszym kadrze na powyższym obrazku widać 4 wyniki żądania interfejsu API dotyczącego zwierząt, posortowane w kolejności alfabetycznej. W drugim kadrze do listy dodawane są kolejne wyniki.

Pierwszy element na liście („Kot”) nie zmienia swojej pozycji początkowej między klatkami, więc jest stabilny. Podobnie nowe elementy dodane do listy nie były wcześniej w DOM, więc ich pozycje początkowe też się nie zmienią. Elementy o nazwach „Dog” (pies), „Horse” (koń) i „Zebra” zmieniają jednak swoje pozycje początkowe, co czyni je niestabilnymi elementami.

Ponownie czerwone prostokąty z przerywanymi krawędziami reprezentują obszary przed i po 3 niestabilnych elementach, które w tym przypadku stanowią około 60% obszaru widoku (ułamek wpływu 0.60).

Strzałki wskazują odległość, jaką niestabilne elementy przemieściły się ze swoich pozycji początkowych. Element „Zebra” oznaczony niebieską strzałką przesunął się najbardziej, o około 30% wysokości widocznego obszaru. W tym przykładzie ułamek odległości wynosi 0.3.

Wynik przesunięcia układu: 0.60 x 0.3 = 0.18.

Oczekiwane i nieoczekiwane przesunięcia układu

Nie wszystkie zmiany układu są złe. Wiele dynamicznych aplikacji internetowych często zmienia pozycję początkową elementów na stronie. Przesunięcie układu jest złe tylko wtedy, gdy użytkownik się go nie spodziewa.

Przesunięcia układu inicjowane przez użytkownika

Przesunięcia układu, które występują w odpowiedzi na interakcje użytkownika (np. kliknięcie lub dotknięcie linku, naciśnięcie przycisku lub wpisanie w polu wyszukiwania), są zazwyczaj dopuszczalne, o ile tylko przesunięcie następuje w takim czasie po interakcji, że związek między nimi jest dla użytkownika jasny.

Jeśli na przykład interakcja z użytkownikiem powoduje wysłanie żądania sieciowego, które może zająć trochę czasu, najlepiej od razu zwolnić trochę miejsca i wyświetlić wskaźnik wczytywania, aby uniknąć nieprzyjemnego przesunięcia układu po zakończeniu żądania. Jeśli użytkownik nie wie, że coś się wczytuje, lub nie ma pojęcia, kiedy zasób będzie gotowy, może podczas oczekiwania kliknąć coś innego, co może zniknąć.

Zmiany układu, które nastąpią w ciągu 500 milisekund od wprowadzenia danych przez użytkownika, będą miały ustawiony parametr hadRecentInput, dzięki czemu można je wykluczyć z obliczeń.

Animacje i przejścia

Dobrze zaprojektowane animacje i przejścia to świetny sposób na aktualizowanie treści na stronie bez zaskakiwania użytkownika. Treści, które nagle i nieoczekiwanie zmieniają się na stronie, prawie zawsze powodują nieprzyjemne wrażenia użytkownika. Jednak treści, które przechodzą stopniowo i naturalnie z jednego położenia w drugie, mogą często pomóc użytkownikowi lepiej zrozumieć, co się dzieje, i poprowadzić go przez zmiany stanu.

Pamiętaj, aby przestrzegać ustawień przeglądarki prefers-reduced-motion, ponieważ niektórzy użytkownicy witryny mogą odczuwać negatywne skutki lub problemy z uwagą spowodowane przez animację.

Właściwość CSS transform pozwala animować elementy bez wywoływania zmian układu:

  • Zamiast zmieniać właściwości heightwidth, użyj właściwości transform: scale().
  • Aby przenosić elementy, nie zmieniaj właściwości top, right, bottom ani left, a zamiast tego używaj właściwości transform: translate().

Jak mierzyć CLS

Wartość CLS można mierzyć w laboratorium lub w warunkach rzeczywistych. Jest ona dostępna w tych narzędziach:

Narzędzia w polu

Narzędzia laboratoryjne

Pomiar przesunięć układu w JavaScript

Aby mierzyć przesunięcia układu w JavaScript, użyj interfejsu Layout Instability API.

Ten przykład pokazuje, jak utworzyć plik PerformanceObserver, aby rejestrować w konsoli wpisy layout-shift:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout shift:', entry);
  }
}).observe({type: 'layout-shift', buffered: true});

Pomiar CLS w JavaScript

Aby mierzyć CLS w JavaScript, musisz pogrupować te nieoczekiwane wpisy layout-shift w sesje i obliczyć maksymalną wartość sesji. Możesz skorzystać z web vitalskodu źródłowego biblioteki JavaScript, który zawiera implementację referencyjną obliczania CLS.

W większości przypadków bieżąca wartość CLS w momencie wyjęcia strony z pamięci jest jej ostateczną wartością, ale są pewne ważne wyjątki, o których piszemy w następnej sekcji. Biblioteka JavaScript web vitals uwzględnia je w jak największym stopniu, biorąc pod uwagę ograniczenia interfejsów API sieciowych.

Różnice między danymi a interfejsem API

  • Jeśli strona jest wczytywana w tle lub jest w tle przed narysowaniem jakichkolwiek treści przez przeglądarkę, nie powinna raportować żadnej wartości CLS.
  • Jeśli strona jest przywracana z pamięci podręcznej stanu strony internetowej, jej wartość CLS powinna zostać zresetowana do zera, ponieważ użytkownicy traktują to jako osobną wizytę na stronie.
  • Interfejs API nie raportuje wpisów layout-shift w przypadku zmian, które występują w ramkach, ale dane to robią, ponieważ są one częścią wrażeń użytkownika na stronie. Może to wyglądać jak różnica między CrUX a RUM. Aby prawidłowo mierzyć CLS, weź je pod uwagę. Ramki podrzędne mogą używać interfejsu API do raportowania swoich wpisów layout-shift do ramki nadrzędnej w celu zbiorczego.

Oprócz tych wyjątków wskaźnik CLS jest bardziej złożony ze względu na to, że mierzy cały czas działania strony:

  • Użytkownicy mogą trzymać kartę otwartą przez bardzo długi czas – przez dni, tygodnie lub miesiące. Użytkownik może nawet nigdy nie zamknąć karty.
  • W systemach operacyjnych na urządzenia mobilne przeglądarki zwykle nie wywołują funkcji wywołania zwrotnego po zwolnieniu strony na kartach w tle, co utrudnia raportowanie „ostatecznej” wartości.

Aby sobie z tym poradzić, CLS powinien być zgłaszany za każdym razem, gdy strona jest w tle, a także za każdym razem, gdy jest ona niewczytana (zdarzenie visibilitychange obejmuje oba te scenariusze). Systemy analityczne otrzymujące te dane będą musiały obliczyć ostateczną wartość CLS na zapleczu.

Zamiast zapamiętywać wszystkie te przypadki i zajmować się nimi, deweloperzy mogą używać biblioteki JavaScript web-vitals do pomiaru CLS, która uwzględnia wszystkie wymienione wyżej przypadki, z wyjątkiem przypadku elementu iframe:

import {onCLS} from 'web-vitals';

// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);

Jak poprawić CLS

Więcej wskazówek dotyczących identyfikowania zmian układu na potrzeby optymalizacji znajdziesz w przewodniku Optymalizowanie CLS.

Dodatkowe materiały

Historia zmian

Czasami w interfejsach API służących do pomiaru danych i czasami w definicjach samych danych występują błędy. W związku z tym czasami trzeba wprowadzić zmiany, które mogą się pojawiać w raportach i panelach wewnętrznych jako ulepszenia lub regresje.

Aby ułatwić Ci zarządzanie tymi danymi, wszystkie zmiany w ich implementacji lub definicji będą widoczne w Historii zmian.

Jeśli masz opinię na temat tych danych, możesz ją przekazać w grupie Google nt. opinii na temat funkcji web-vitals.