Dowiedz się, jak rozpoznawać i rozwiązywać problemy z przesunięciami układu.
W pierwszej części tego artykułu omawiamy narzędzia do debugowania przesunięć układu, a w drugiej – proces myślowy przy identyfikowaniu przyczyny przesunięcia układu.
Narzędzia
Interfejs Layout Instability API
Układ interfejsu Instability API służy do pomiaru i raportowania przesunięć układu przeglądarki. Wszystkie narzędzia do debugowania przesunięć układu, w tym Narzędzia deweloperskie, opierają się ostatecznie na interfejsie Layout Instability API. Korzystanie z interfejsu Layout Instability API jest jednak wszechstronnym narzędziem do debugowania ze względu na jego elastyczność.
Wykorzystanie
Do debugowania przesunięć układu może służyć ten sam fragment kodu, który mierzy skumulowane przesunięcie układu (CLS). Poniższy fragment kodu zawiera informacje o przenoszeniu układu do konsoli. Przeanalizuj ten dziennik, aby dowiedzieć się, kiedy, gdzie i jak doszło do przesunięcia 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});
Uruchamiając ten skrypt, pamiętaj, że:
- Opcja
buffered: true
wskazuje, żePerformanceObserver
powinien sprawdzać w buforze wpisów wydajności przeglądarki pod kątem wpisów dotyczących wydajności, które zostały utworzone przed inicjowaniem obserwatora. W efekciePerformanceObserver
będzie raportować przesunięcia układu, które nastąpiły zarówno przed jego zainicjowaniem, jak i po nim. Pamiętaj o tym podczas analizowania logów konsoli. Początkowe przesunięcia układu mogą odzwierciedlać zaległości w raportach, a nie nagłe wystąpienie wielu zmian układu. - Aby uniknąć negatywnego wpływu na wydajność,
PerformanceObserver
czeka, aż wątek główny będzie nieaktywny, i będzie przesyłać raporty o przesunięciach układu. W zależności od tego, jak zajęty jest wątek główny, między momentem przesunięcia układu a zarejestrowaniem go w konsoli może wystąpić niewielkie opóźnienie. - Ten skrypt ignoruje przesunięcia układu, które nastąpiły w ciągu 500 ms od użytkownika i dlatego nie są uwzględniane w CLS.
Informacje o przesunięciach układu są raportowane przy użyciu kombinacji 2 interfejsów API: LayoutShift
i LayoutShiftAttribution
. Każdy z tych interfejsów został szczegółowo wyjaśniony w kolejnych sekcjach.
LayoutShift
Każde przesunięcie układu jest raportowane za pomocą interfejsu LayoutShift
. Zawartość tego wpisu wygląda tak:
duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798
Powyższy wpis wskazuje przesunięcie układu, podczas którego zmieniły się 3 elementy DOM. Wynik przesunięcia układu dla tego konkretnego przesunięcia układu wyniósł 0.175
.
Oto właściwości instancji LayoutShift
, które są najbardziej przydatne przy debugowaniu przesunięć układu:
Właściwość | Opis |
---|---|
sources |
Właściwość sources zawiera listę elementów DOM, które zostały przeniesione podczas przesunięcia układu. Ta tablica może zawierać maksymalnie 5 źródeł. Jeśli przesunięcie układu wpływa na więcej niż 5 elementów, raportowanych jest 5 największych (mierzonych przez wpływ na stabilność układu) źródeł przesunięcia układu. Te informacje są raportowane za pomocą interfejsu atrybucji LayoutShift Attribution (szczegóły poniżej). |
value |
Właściwość value podaje wynik przesunięcia układu dla określonego przesunięcia układu. |
hadRecentInput |
Właściwość hadRecentInput wskazuje, czy zmiana układu nastąpiła w ciągu 500 milisekund od danych wejściowych użytkownika. |
startTime |
Właściwość startTime wskazuje, kiedy miało miejsce przesunięcie układu. Wartość startTime jest podawana w milisekundach i mierzona względem czasu rozpoczęcia wczytywania strony. |
duration |
Właściwość duration będzie zawsze ustawiona na 0 . Ta właściwość jest dziedziczona z interfejsu PerformanceEntry (interfejs LayoutShift rozszerza interfejs PerformanceEntry ). Pojęcie czasu trwania nie dotyczy jednak zdarzeń przesunięcia układu, więc ma wartość 0 . Informacje o interfejsie PerformanceEntry znajdziesz w spec. |
LayoutShiftAttribution
Interfejs LayoutShiftAttribution
opisuje jedno przesunięcie pojedynczego elementu DOM. Jeśli podczas przesunięcia układu przesunie się wiele elementów, właściwość sources
zawiera wiele wpisów.
Na przykład poniższy kod JSON odpowiada przesunięciem układu z jednego źródła: przesunięciem elementu DOM <div id='banner'>
w dół z y: 76
do y:246
.
// ...
"sources": [
{
"node": "div#banner",
"previousRect": {
"x": 311,
"y": 76,
"width": 4,
"height": 18,
"top": 76,
"right": 315,
"bottom": 94,
"left": 311
},
"currentRect": {
"x": 311,
"y": 246,
"width": 4,
"height": 18,
"top": 246,
"right": 315,
"bottom": 264,
"left": 311
}
}
]
Właściwość node
identyfikuje przesunięty element HTML. Najechanie kursorem na tę właściwość w Narzędziach deweloperskich spowoduje podświetlenie odpowiedniego elementu strony.
Właściwości previousRect
i currentRect
podają rozmiar i pozycję węzła.
- Współrzędne
x
iy
podają współrzędne X i Y zależnie od lewego górnego rogu elementu - Właściwości
width
iheight
podają odpowiednio szerokość i wysokość elementu. - Właściwości
top
,right
,bottom
ileft
podają wartości współrzędnych x lub y odpowiadające danej krawędzi elementu. Innymi słowy, wartośćtop
jest równay
, a wartośćbottom
równa sięy+height
.
Jeśli wszystkie właściwości elementu previousRect
mają wartość 0, oznacza to, że element stał się widoczny. Jeśli wszystkie właściwości elementu currentRect
mają wartość 0, oznacza to, że element przesunął się poza widok.
Jedną z najważniejszych kwestii, o której należy pamiętać przy interpretowaniu tych danych, jest to, że elementy wymienione jako źródła to elementy, które przesunęły się podczas zmiany układu. Możliwe jednak, że te elementy są tylko pośrednio związane z „główną przyczyną” niestabilności układu. Oto kilka przykładów:
Przykład 1
To przesunięcie układu zostanie odnotowane z jednym źródłem: elementem B. Główną przyczyną tego przesunięcia układu jest jednak zmiana rozmiaru elementu A.
Przykład 2
Przesunięcie układu w tym przykładzie zostanie odnotowane z 2 źródeł: elementu A i elementu B. Główną przyczyną tego przesunięcia układu jest zmiana położenia elementu A.
Przykład 3
Przesunięcie układu w tym przykładzie zostanie odnotowane z jednym źródłem: elementem B. Zmiana pozycji elementu B spowodowała przesunięcie układu.
Przykład 4
Choć element B zmienia rozmiar, w tym przykładzie nie ma przesunięcia układu.
Zapoznaj się z prezentacją zmian DOM raportowanych przez interfejs Layout Instability API.
DevTools
Panel wydajności
W panelu Możliwości w panelu Wydajność Narzędzi deweloperskich widać wszystkie zmiany układu, które zachodzą w danym śladzie wydajności nawet wtedy, gdy mają miejsce w ciągu 500 ms od interakcji użytkownika i dlatego nie są uwzględniane w CLS. Najechanie kursorem na określone przesunięcie układu w panelu Możliwości wyróżnia dany element DOM.
Aby wyświetlić więcej informacji o przesunięciu układu, kliknij to przesunięcie układu, a następnie otwórz szufladę Podsumowanie. Zmiany wymiarów elementu są podawane w formacie [width, height]
. Zmiany pozycji elementu są podawane w formacie [x,y]
. Właściwość Zawiera ostatnie dane wejściowe wskazuje, czy zmiana układu nastąpiła w ciągu 500 ms od interakcji użytkownika.
Aby uzyskać informacje o czasie trwania przesunięcia układu, otwórz kartę Dziennik zdarzeń. Czas trwania przesunięcia układu można też oszacować, sprawdzając w panelu Możliwości długość czerwonego prostokąta przesunięcia układu.
Więcej informacji o korzystaniu z panelu Wydajność znajdziesz w dokumentacji analizy wydajności.
Podświetl regiony przesunięcia układu
Zaznaczanie obszarów przesunięcia układu może być przydatną techniką pozwalającą szybko i szybko poznać lokalizację i czas wprowadzania przesunięć układu na stronie.
Aby włączyć regiony przesunięcia układu w Narzędziach deweloperskich, otwórz Ustawienia > Więcej narzędzi > Renderowanie > Regiony przesunięcia układu, a potem odśwież stronę, którą chcesz debugować. Obszary przesunięcia układu będą przez chwilę podświetlone na fioletowo.
Proces myślenia o przyczynie przesunięć układu
Skorzystaj z poniższych instrukcji, aby zidentyfikować przyczynę przesunięcia układu niezależnie od tego, kiedy i jak ma ono miejsce. Te czynności można uzupełnić o uruchomienie narzędzia Lighthouse, ale pamiętaj, że Lighthouse może wykrywać tylko przesunięcia układu, które nastąpiły podczas wstępnego wczytywania strony. Dodatkowo Lighthouse może też sugerować tylko niektóre przyczyny przesunięcia układu, np. elementy obrazu, które nie mają wyraźnej szerokości ani wysokości.
Określanie przyczyny przesunięcia układu
Przesunięcia układu mogą być spowodowane tymi zdarzeniami:
- zmiana położenia elementu DOM.
- zmiany wymiarów elementu DOM.
- Wstawienie lub usunięcie elementu DOM
- Animacje, które aktywują układ
W szczególności element DOM bezpośrednio poprzedzający przesunięty element jest elementem, który z największym prawdopodobieństwem zostanie uwzględniony w „powodowaniu” przesunięcia układu. Aby więc ustalić, dlaczego doszło do zmiany układu, weź pod uwagę te kwestie:
- Czy zmieniła się pozycja lub wymiary poprzedniego elementu?
- Czy element DOM został wstawiony przed przesuniętym elementem lub usunięty?
- Czy położenie przesuniętego elementu zostało wyraźnie zmienione?
Jeśli poprzedni element nie spowodował przesunięcia układu, kontynuuj wyszukiwanie, uwzględniając inne poprzedzające i pobliskie elementy.
Kierunek i odległość przesunięcia układu mogą też dostarczać wskazówek o głównej przyczynie. Na przykład duże przesunięcie w dół często oznacza wstawienie elementu DOM, natomiast przesunięcie układu o 1 lub 2 piksele często oznacza zastosowanie sprzecznych stylów CSS lub wczytania i zastosowania czcionki internetowej.
Oto niektóre zachowania, które najczęściej powodują zdarzenia przesunięcia układu:
zmiany położenia elementu (nie wynikają z ruchu innego elementu).
Taka zmiana jest często efektem:
- Arkusze stylów, które są ładowane z opóźnieniem, lub zastępują wcześniej zadeklarowane style.
- Efekty animacji i przejścia.
Zmiany wymiarów elementu
Taka zmiana jest często efektem:
- Arkusze stylów, które są ładowane z opóźnieniem, lub zastępują wcześniej zadeklarowane style.
- Obrazy i elementy iframe bez atrybutów
width
iheight
, które są wczytywane po wyrenderowaniu boksu. - Bloki tekstu bez atrybutów
width
lubheight
, które po wyrenderowaniu tekstu zamieniają czcionki.
Wstawianie lub usuwanie elementów DOM
Często jest to spowodowane tymi sytuacjami:
- Wstawianie reklam i umieszczanie reklam innych firm.
- Wstawianie banerów, alertów i okna modalnego.
- nieskończone przewijanie i inne wzorce UX, które wczytują dodatkowe treści ponad istniejącą treścią.
Animacje, które aktywują układ
Niektóre efekty animacji mogą wywoływać układ. Typowym przykładem jest sytuacja, w której elementy DOM są „animowane” przez zwiększanie właściwości takich jak top
lub left
zamiast użycia właściwości transform
CSS. Więcej informacji znajdziesz w artykule Jak tworzyć animacje CSS o dużej skuteczności.
Odtwarzanie przesunięć układu
Nie możesz naprawić przesunięć układu, których nie można odtworzyć. Jedną z najprostszych i najefektywniejszych rzeczy, które można zrobić, aby lepiej poznać stabilność układu witryny, jest poświęcenie 5–10 minut na interakcję z witryną w celu wywołania zmian układu. W tym czasie pozostaw konsolę otwartą i używaj interfejsu Layout Instability API, aby raportować przesunięcia układu.
Jeśli trudno jest znaleźć takie zmiany, możesz powtórzyć to ćwiczenie na różnych urządzeniach i przy różnych szybkościach połączenia. W szczególności wolne połączenie może ułatwić
wykrycie zmian układu. Aby ułatwić sobie przechodzenie między zmianami układu, możesz też użyć instrukcji debugger
.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
cls += entry.value;
debugger;
console.log('Current CLS value:', cls, entry);
}
}
}).observe({type: 'layout-shift', buffered: true});
W przypadku problemów z układem, których nie da się odtworzyć w programie, rozważ użycie interfejsu Layout Instability API w połączeniu z wybranym narzędziem do logowania w interfejsie, aby zebrać więcej informacji na ich temat. Zapoznaj się z przykładowym kodem śledzenia największego przesuniętego elementu na stronie.