Debuguj przesunięcia układu

Dowiedz się, jak wykrywać i naprawiać przesunięcia układu.

Data publikacji: 11 marca 2021 r., ostatnia aktualizacja: 7 lutego 2025 r.

Pierwsza część tego artykułu omawia narzędzia do debugowania zmian układu, a druga – proces myślenia, którego należy używać do identyfikowania przyczyny zmiany układu.

Możesz debugować zmiany układu za pomocą interfejsu Layout Instability API lub narzędzi takich jak DevTools, które podsumowują dane z tego interfejsu API w bardziej przystępnym formacie.

Interfejs API niestabilności układu to mechanizm przeglądarki służący do pomiaru i raportowania zmian układu. Wszystkie narzędzia do debugowania przesunięć układu, w tym DevTools, są ostatecznie oparte na interfejsie Layout Instability API. Jednak bezpośrednie korzystanie z interfejsu Layout Instability API jest skutecznym narzędziem do debugowania ze względu na jego elastyczność.

Wykorzystanie

Ten sam kod fragmentu kodu, który mierzy skumulowane przesunięcie układu (CLS), może też służyć do debugowania przesunięć układu. Ten fragment kodu rejestruje w konsoli informacje o przesunięciu układu. Przeanalizowanie tego pliku dziennika pozwoli Ci dowiedzieć się, kiedy, gdzie i jak nastąpiła zmiana 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 uruchamiania tego skryptu pamiętaj, że:

  • Opcja buffered: true wskazuje, że PerformanceObserver powinna sprawdzić bufor danych o wydajności przeglądarki pod kątem wpisów o wydajności, które zostały utworzone przed zainicjowaniem obserwatora. W rezultacie funkcja PerformanceObserver będzie raportować zmiany układu, które wystąpiły zarówno przed jej zainicjowaniem, jak i po nim. Pamiętaj o tym, gdy sprawdzasz logi konsoli. Początkowy napływ zmian układu może odzwierciedlać zaległości w raportowaniu, a nie nagłe wystąpienie wielu zmian układu.
  • Aby uniknąć wpływu na wydajność, funkcja PerformanceObserver czeka, aż główny wątek będzie bezczynny, aby przekazać informacje o przesunięciach układu. W zależności od obciążenia wątku głównego może wystąpić niewielkie opóźnienie między wystąpieniem zmiany układu a jej zarejestrowaniem w konsoli.
  • Ten skrypt ignoruje zmiany układu, które nastąpiły w ciągu 500 ms od wprowadzenia danych przez użytkownika, i dlatego nie są one uwzględniane w wyrażeniu CLS.

Informacje o przesunięciu układu są raportowane za pomocą kombinacji 2 interfejsów API: LayoutShiftLayoutShiftAttribution. W następnych sekcjach znajdziesz więcej informacji o każdym z tych interfejsów.

LayoutShift

Każda zmiana układu jest zgłaszana za pomocą interfejsu LayoutShift. Treść 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

Poprzedni wpis wskazuje zmianę układu, podczas której 3 elementy DOM zmieniły położenie. Wynik przesunięcia układu w przypadku tego konkretnego przesunięcia układu wynosił 0.175.

Oto właściwości wystąpienia LayoutShift, które są najbardziej przydatne do debugowania przesunięć układu:

Właściwość Opis
sources Właściwość sources zawiera listę elementów DOM, które zostały przeniesione podczas zmiany układu. Ta tablica może zawierać maksymalnie 5 źródeł. Jeśli przesunięcie układu ma wpływ na więcej niż 5 elementów, raportowane są 5 największych (mierzonych pod kątem wpływu na stabilność układu) źródeł przesunięcia układu. Te informacje są raportowane za pomocą interfejsu LayoutShiftAttribution (więcej informacji znajdziesz poniżej).
value Usługa value raportuje wynik przesunięcia układu dla konkretnego przesunięcia układu.
hadRecentInput Właściwość hadRecentInput wskazuje, czy przesunięcie układu nastąpiło w ciągu 500 milisekund od wprowadzenia danych przez użytkownika.
startTime Właściwość startTime wskazuje, kiedy nastąpiła zmiana układu. Wartość startTime jest podawana w milisekundach i jest mierzona w odniesieniu do czasu zainicjowania 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). Jednak pojęcie czasu trwania nie ma zastosowania do zdarzeń zmiany układu, więc jest ono ustawione na 0. Informacje o interfejsie PerformanceEntry znajdziesz w specyfikacji.

LayoutShiftAttribution

Interfejs LayoutShiftAttribution opisuje pojedynczy przesunięcie pojedynczego elementu DOM. Jeśli podczas przesunięcia układu przesuwa się wiele elementów, właściwość sources zawiera wiele wpisów.

Na przykład poniższy kod JSON odpowiada przesunięciu układu z 1 źródłem: przesunięcie w dół elementu DOM <div id='banner'> z pozycji y: 76 do pozycji 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 element HTML, który został przesunięty. Najechanie kursorem na tę właściwość w Narzędziach deweloperskich podświetla odpowiadający element strony.

Właściwości previousRectcurrentRect podają rozmiar i położenie węzła.

  • współrzędne xy podają odpowiednio współrzędną x i y lewego górnego rogu elementu;
  • Właściwości width i height podają odpowiednio szerokość i wysokość elementu.
  • Właściwości top, right, bottomleft podają wartości współrzędnych x lub y odpowiadające danej krawędzi elementu. Innymi słowy, wartość top jest równa y, a wartość bottom jest równa y+height.

Jeśli wszystkie właściwości previousRect mają wartość 0, oznacza to, że element został przesunięty do widoku. Jeśli wszystkie właściwości elementu currentRect mają wartość 0, oznacza to, że element jest poza widokiem.

Najważniejsze, co należy wiedzieć podczas interpretowania tych danych wyjściowych, to fakt, że elementy wymienione jako źródła to elementy, które zostały przeniesione podczas zmiany układu. Możliwe jednak, że te elementy są tylko pośrednio powiązane z „główną przyczyną” niestabilności układu. Oto kilka przykładów:

Przykład 1

Ta zmiana układu zostałaby zgłoszona z jednego źródła: elementu B. Jednak główną przyczyną tego przesunięcia układu jest zmiana rozmiaru elementu A.

Przykład pokazujący zmianę układu spowodowaną zmianą wymiarów elementu

Przykład 2

W tym przykładzie zmiana układu zostałaby zgłoszona z 2 źródłami: elementem A i elementem B. Główną przyczyną tego przesunięcia układu jest zmiana pozycji elementu A.

Przykład pokazujący zmianę układu spowodowaną zmianą pozycji elementu

Przykład 3

W tym przykładzie zmiana układu zostałaby zaraportowana z jednym źródłem: elementem B. Zmiana pozycji elementu B spowodowała przesunięcie układu.

Przykład pokazujący zmianę układu spowodowaną zmianą pozycji elementu

Przykład 4

Chociaż element B zmienia rozmiar, w tym przykładzie nie ma przesunięcia układu.

Przykład elementu, który zmienia rozmiar, ale nie powoduje zmiany układu

Obejrzyj prezentację, która pokazuje, jak zmiany w DOM są zgłaszane przez interfejs API niestabilności układu.

Narzędzia deweloperskie

W DevTools jest kilka narzędzi, które ułatwiają debugowanie zmian układu.

Panel wydajności

Widok danych na żywo w panelu Wydajność umożliwia interakcję ze stroną i monitorowanie wyniku CLS, aby wykrywać interakcje powodujące duże przesunięcia układu.

Rekordy zmiany układu wyświetlane na ekranie danych na żywo w panelu wydajności w Narzędziach deweloperskich w Chrome.
W panelu Skuteczność widok danych na żywo umożliwia monitorowanie wyniku CLS strony internetowej podczas interakcji z nią.

Gdy uda Ci się odtworzyć zmianę układu, możesz przeprowadzić śledzenie, aby uzyskać jeszcze więcej informacji:

Rekordy zmiany układu wyświetlane w panelu wydajności w Narzędziach deweloperskich w Chrome.
Po zarejestrowaniu nowego śladu w panelu „Wydajność” ścieżka wyników Zmiana układu jest wypełniona fioletowymi paskami, które wskazują Layout Shift skupiska. Kliknięcie diamentów powoduje wyświetlenie animacji przesunięcia i szczegółów w panelu Podsumowanie.

Przesunięcia układu są wyróżnione na ścieżce Przesunięcia układu. Grupy fioletowych linii zmieniają się w grupy przesunięć, a diamenty wskazują poszczególne przesunięcia w danym skupieniu. Rozmiar diamentu jest proporcjonalny do wielkości przesunięcia, co pozwala skupić się na największych przesunięciach.

Kliknięcie przesunięcia powoduje wyświetlenie wyskakującego okienka z animacją przesunięcia i wyróżnienie elementów w fioletowym kolorze.

Dodatkowo widok Podsumowanie rekordu Layout Shift zawiera czas rozpoczęcia, wynik przesunięcia oraz elementy przesunięte. Jest to szczególnie przydatne, jeśli chcesz uzyskać więcej informacji o problemach z CLS podczas wczytywania, ponieważ można je łatwo odtworzyć za pomocą profilu wydajności przy ponownym wczytaniu.

Linkuje się on też z informacjami Przyczyny zmian układu wyświetlanymi w panelu Statystyki po lewej stronie. U góry znajdziesz tam łączną wartość CLS, a także możliwe przyczyny zmian układu.

Więcej informacji o używaniu panelu Wydajność znajdziesz w tabelce referencyjnej dotyczącej analizy skuteczności.

Podświetlanie regionów przesunięcia układu

Podświetlanie regionów przesunięcia układu może być przydatną techniką, która pozwala szybko i na pierwszy rzut oka określić lokalizację i czas przesunięcia układu na stronie.

Aby włączyć Regiony przesunięcia układu w Narzędziach deweloperskich, kliknij Ustawienia > Więcej narzędzi > Rendering > Regiony przesunięcia układu, a następnie odśwież stronę, którą chcesz debugować. Obszary przesunięcia układu będą krótko wyróżnione na różowo.

Sposób identyfikowania przyczyn przesunięć układu

Aby określić przyczynę zmian układu, wykonaj podane niżej czynności niezależnie od tego, kiedy i jak nastąpiła zmiana. Możesz je uzupełnić o wykorzystanie Lighthouse. Pamiętaj jednak, że Lighthouse może wykryć tylko przesunięcia układu, które wystąpiły podczas początkowego wczytywania strony. Poza tym Lighthouse może podać sugestie tylko w przypadku niektórych przyczyn zmian układu, np. elementów obrazu, które nie mają wyraźnej szerokości ani wysokości.

Określanie przyczyny przesunięcia układu

Zmiany układu mogą być spowodowane przez te zdarzenia:

  • Zmiany pozycji elementu DOM
  • Zmiany wymiarów elementu DOM
  • wstawianie lub usuwanie elementu DOM;
  • Animacje, które wywołują układ

W szczególności element DOM bezpośrednio poprzedzający przesunięty element jest elementem, który najprawdopodobniej „spowodował” przesunięcie układu. Dlatego podczas sprawdzania, dlaczego doszło do przesunięcia układu, weź pod uwagę:

  • Czy pozycja lub wymiary poprzedniego elementu uległy zmianie?
  • Czy przed przesuniętym elementem został wstawiony lub usunięty element DOM?
  • Czy pozycja przesuniętego elementu została zmieniona?

Jeśli poprzedni element nie spowodował zmiany układu, kontynuuj wyszukiwanie, biorąc pod uwagę inne poprzednie elementy i elementy znajdujące się w pobliżu.

Dodatkowo kierunek i odległość przesunięcia układu mogą wskazywać na przyczynę. Na przykład duży przesunięcie w dół często wskazuje na wstawienie elementu DOM, a przesunięcie układu o 1 px lub 2 px często wskazuje na zastosowanie sprzecznych stylów CSS lub wczytanie i zastosowanie czcionki internetowej.

Diagram pokazujący zmianę układu spowodowaną wymianą czcionki
W tym przykładzie zamiana czcionki spowodowała przesunięcie elementów strony o 5 pikseli w górę.

Oto niektóre z działań, które najczęściej powodują przesunięcia układu:

zmiany pozycji elementu (które nie są spowodowane ruchem innego elementu);

Ten typ zmiany jest często spowodowany:

  • Arkusze stylów, które są ładowane późno lub zastępują wcześniej zadeklarowane style.
  • Efekty animacji i przejść.

zmiany wymiarów elementu,

Ten typ zmiany jest często spowodowany:

  • Arkusze stylów, które są ładowane późno lub zastępują wcześniej zadeklarowane style.
  • obrazy i ramki iframe bez atrybutów widthheight, które są renderowane po wyświetleniu ich „miejsca”;
  • Bloki tekstowe bez atrybutów width lub height, które zamieniają czcionki po renderowaniu tekstu.

wstawianie lub usuwanie elementów DOM;

Zwykle jest to spowodowane:

  • Wstawianie reklam i innych elementów innych firm.
  • Wstawianie banerów, alertów i modali.
  • Nieskończone przewijanie i inne wzorce interakcji, które wczytują dodatkowe treści nad istniejącymi treściami.

Animacje, które wywołują układ

Niektóre efekty animacji mogą uruchomić układ. Typowym przykładem jest „animowanie” elementów DOM przez zwiększanie wartości właściwości takich jak top lub left zamiast używania właściwości transform w CSS. Więcej informacji znajdziesz w artykule Tworzenie wydajnych animacji CSS.

Odtwarzanie przesunięć układu

Nie możesz naprawić przesunięć układu, których nie możesz odtworzyć. Jednym z najprostszych, a jednocześnie najskuteczniejszych sposobów na uzyskanie lepszego pojęcia stabilności układu witryny jest poświęcenie 5–10 minut na interakcję z witryną w celu wywołania zmian układu. Podczas tego procesu konsola powinna być otwarta, a aby zgłaszać zmiany układu, należy użyć interfejsu API niestabilności układu.

Jeśli trudno Ci znaleźć zmiany układu, powtórz to ćwiczenie na różnych urządzeniach i przy różnych szybkościach połączenia. W szczególności wolniejsze połączenie ułatwia wykrywanie zmian układu. Aby ułatwić sobie przechodzenie przez zmiany 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 można odtworzyć w procesie tworzenia aplikacji, rozważ użycie interfejsu API niestabilności układu w połączeniu z wybranym przez Ciebie narzędziem do rejestrowania danych z frontendu, aby uzyskać więcej informacji o tych problemach. Sprawdź przykład kodu, który pozwala śledzić największy przesunięty element na stronie.