Nieoczekiwane zmiany układu mogą na wiele sposobów przeszkadzać użytkownikom: mogą np. stracić informacje o swoim miejscu podczas czytania w przypadku nagłego przesunięcia tekstu lub skłonić go do kliknięcia niewłaściwego linku lub przycisku. W niektórych przypadkach może to spowodować poważne uszkodzenia.
Nieoczekiwane przemieszczanie się treści na stronie występuje zwykle, 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 działa witryna 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.
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.
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
Przesunięcia układu są definiowane przez interfejs Layout Instability API. Raportuje on wpisy layout-shift
za każdym razem, gdy element widoczny w widocznym obszarze zmieni swoją pozycję początkową (na przykład jego górną i lewą pozycję w domyślnym trybie zapisu) między 2 klatkami. 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ływu i ułamka odległości (obie definicje znajdują się poniżej).
layout shift score = impact fraction * distance fraction
Frakcja wpływu
Ułamek wpływu pokazuje, jak niestabilne elementy wpływają na obszar widocznego obszaru 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.
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łego 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ść, w jakiej elementy niestabilne zostały przesunięte 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).
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:
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 modelu DOM, więc jego pozycja początkowa również się nie zmienia.
Początkowa pozycja zielonego pola się zmienia, ale ponieważ zostało ono częściowo przeniesione poza widok, 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
.
Odsetek 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:
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 to 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 szkodliwe tylko wtedy, gdy użytkownik tego nie spodziewa.
Przesunięcia układu inicjowane przez użytkownika
Zmiany układu występujące w odpowiedzi na interakcje użytkowników (takie jak kliknięcie linku, naciśnięcie przycisku czy wpisanie tekstu w polu wyszukiwania) są zwykle normalne, o ile przesunięcie następuje na tyle blisko interakcji, że relacja jest jasna dla użytkownika.
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ąć.
Przesunięcia układu występujące w ciągu 500 milisekund od wprowadzenia danych przez użytkownika będą miały ustawioną flagę hadRecentInput
, więc można je wykluczyć z obliczenia.
Animacje i przejścia
Dobre animacje i przejścia to świetny sposób na aktualizację zawartości strony bez zaskakiwania użytkowników. Treści, które gwałtownie i nieoczekiwanie zmieniają się na stronie, niemal zawsze wywołują negatywne wrażenia u użytkowników. Jednak treści, które przesuwają się stopniowo i naturalnie z jednej pozycji do drugiej, często mogą pomóc użytkownikowi w lepszym zrozumieniu tego, co dzieje się na ekranie i przekierowaniu go do kolejnych zmian 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
height
iwidth
, użyj właściwościtransform: scale()
. - Aby przenosić elementy, nie zmieniaj właściwości
top
,right
,bottom
anileft
. Zamiast nich użyj właściwościtransform: 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
- Raport na temat użytkowania Chrome
- PageSpeed Insights
- Search Console (raport Core Web Vitals)
web-vitals
Biblioteka JavaScript
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ć PerformanceObserver
w celu rejestrowania wpisów layout-shift
w konsoli:
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 języku JavaScript, musisz zgrupować te nieoczekiwane wpisy layout-shift
w sesje i obliczyć maksymalną wartość sesji. Możesz skorzystać z web vitals
kodu ź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 te dane w jak największym stopniu, z zastrzeżeniem ograniczeń interfejsów API sieci Web.
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 zgłaszać ż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ówlayout-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 uwzględnić takie przypadki, CLS należy zgłaszać za każdym razem, gdy strona działa w tle – a nie tylko wtedy, gdy zostanie wyładowana z pamięci (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 rozwiązywać je samodzielnie, 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
- Wytyczne dotyczące tagu wydawcy Google dotyczące minimalizowania przesunięcia układu
- Znajomość kumulatywnego przesunięcia układu autorstwa Annie Sullivan i Steve’a Kobesa na konferencji #PerfMatters (2020 r.)
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. danych web-vitals.