Debuguj przesunięcia układu

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

Katie Hempenius
Katie Hempenius

W pierwszej części tego artykułu omawiamy narzędzia do debugowania przesunięć układu, W drugiej części omawiamy proces myślowy, który można zastosować aby znaleźć przyczynę przesunięcia układu.

Narzędzia

Interfejs Layout Instability API

Interfejs API niestabilności układu to mechanizm przeglądarki służący do pomiaru i raportowania zmian układu. Wszystkie narzędzia dla przesunięcia układu debugowania, w tym Narzędzia deweloperskie, są ostatecznie oparte na Layout Instability API. Bezpośrednie używanie interfejsu Layout Instability API potężnym narzędziu do debugowania ze względu na swoją 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. Fragment poniżej zawiera informacje o układzie przechodzi do konsoli. W tym pliku znajdziesz informacje o tym, 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. powinien sprawdzić wpis wydajności przeglądarki bufor dla wpisów dotyczących wydajności, które zostały utworzone przed jego zainicjowanie. W rezultacie funkcja PerformanceObserver będzie raportować zmiany układu, które wystąpiły zarówno przed jej zainicjowaniem, jak i po nim. Zachowaj w podczas sprawdzania dzienników konsoli. Początkowy efekt przesunięć układu może odzwierciedlają zaległości w raportach, a nie nagłe wystąpienie wielu przesunięcia 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 tego, jak jest zajęty wątekem głównym, może wystąpić niewielkie opóźnienie między momentem pojawienia się układu zachodzi zmiana i gdy zostanie ona zarejestrowana 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ą uwzględniane w wyrażeniu CLS.

Informacje o przesunięciach układu są zgłaszane przy użyciu kombinacji 2 interfejsów API: LayoutShift i LayoutShiftAttribution i interfejsów. W następnych sekcjach znajdziesz więcej informacji o każdym z tych interfejsów.

Przesunięcie układu

Każde przesunięcie układu jest raportowane w interfejsie LayoutShift. Zawartość pojawi się taki wpis:

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, w wyniku którego zmieniły się 3 elementy DOM. pozycji. Wynik przesunięcia układu w przypadku tego konkretnego przesunięcia układu wyniósł 0.175.

To są właściwości instancji LayoutShift, które są najważniejsze dla debugowanie 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 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 (zostało to szczegółowo opisane 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 wystąpiło przesunięcie układu. Wartość startTime jest podawana w milisekundach i mierzona względem czasu zainicjowania wczytywania strony.
duration Właściwość duration będzie zawsze mieć wartość 0. Ta właściwość jest dziedziczona z interfejsu PerformanceEntry (interfejs LayoutShift rozszerza interfejs PerformanceEntry). Czas trwania nie dotyczy jednak zdarzeń przesunięcia układu, więc ma wartość 0. Informacje o interfejsie PerformanceEntry znajdziesz w specyfikacji.

LayoutShiftAttribution

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

Na przykład poniższy plik JSON odpowiada przesunięciu układu z jednym źródłem: przesunięcie w dół elementu DOM <div id='banner'> z y: 76 na 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 odpowiedni element strony.

Właściwości previousRect i currentRect raportują rozmiar i pozycję węzła.

  • Współrzędne x i y wskazują współrzędne X i Y. odpowiednio w lewym górnym 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 obiektu previousRect mają wartość 0, oznacza to, że element jest widoczny. 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 przesunięte 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 1 źródłem: elementem B. Jednak główną przyczyną tego przesunięcia układu jest zmiana rozmiaru elementu A.

Przykład przedstawiający przesunięcie układu spowodowane zmianą wymiarów elementu

Przykład 2

Przesunięcie układu w tym przykładzie zostałoby zaraportowane z użyciem 2 źródeł: element A i elementu 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 to przesunięcie układu.

Przykład przedstawiający przesunięcie układu spowodowane 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ę dotyczącą raportowania zmian DOM przez interfejs Layout Instability API.

Narzędzia deweloperskie

Panel wydajności

W panelu Wrażenia w DevTools w panelu Wydajność są wyświetlane wszystkie przesunięcia układu, które występują podczas danego śledzenia wydajności, nawet jeśli występują w ciągu 500 ms od interakcji użytkownika i dlatego nie są uwzględniane w wyrażeniu CLS. Najechanie kursorem na konkretne przesunięcie układu w panelu Doświadczenie podświetla element DOM, na który ma ono wpływ.

Zrzut ekranu przedstawiający zmianę układu wyświetlaną w panelu Sieć w Narzędziach deweloperskich

Aby wyświetlić więcej informacji o przesunięciu układu, kliknij to przesunięcie, a potem otwórz panel Podsumowanie. Zmiany wymiarów elementów są widoczne na liście. użyj formatu [width, height]; zmiany pozycji elementu są podane musi mieć format [x,y]. Właściwość Wprowadzono ostatnie dane wejściowe wskazuje, czy przesunięcie układu nastąpiło w ciągu 500 ms od interakcji użytkownika.

Zrzut ekranu z podsumowaniem w Narzędziach deweloperskich Tab, gdzie znajdziesz przesunięcie układu

Aby uzyskać informacje o czasie trwania zmiany układu, otwórz kartę Dziennik zdarzeń. Czas trwania przesunięcia układu można również oszacować, patrząc na Okienko eksperymentu odpowiadające długości czerwonego prostokąta przesunięcia układu.

Zrzut ekranu z kartą „Event Log” (Dziennik zdarzeń) w Narzędziach dla programistów w przypadku przesunięcia układu

Więcej informacji o używaniu panelu Wydajność znajdziesz w tabelce „Wydajność” w sekcji „Przewodnik po analizie”.

Wyróżnij regiony 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 > Renderowanie > Regiony przesunięcia układu, a następnie odśwież stronę, którą chcesz debugować. Obszary przesunięcia układu są krótko podświetlone na fioletowo.

Sposób identyfikowania przyczyn przesunięć układu

Wykonaj podane niżej czynności, aby określić przyczynę zmian układu, niezależnie od tego, kiedy i jak one występują. Te czynności można wykonać uzupełniony o uruchomienie Lighthouse. Pamiętaj jednak, że możesz identyfikować przesunięcia układu, które miały miejsce podczas początkowego wczytywania strony. Ponadto 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.

Identyfikowanie 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

Element DOM bezpośrednio poprzedzający przesunięty element to element, który ma największe szanse na udział w „powodowaniu” przesunięcia układu. Dlatego gdy aby sprawdzić, dlaczego doszło do przesunięcia układu, rozważ:

  • Czy zmieniły się położenie lub wymiary poprzedniego elementu?
  • 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ł przesunięcia układu, kontynuuj wyszukiwanie według z uwzględnieniem innych elementów poprzedzających i pobliskich.

Kierunek i odległość przesunięcia układu mogą też pomóc o głównej przyczynie. 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 czcionek spowodowała przesunięcie elementów strony w górę o 5 pikseli.

Oto niektóre zachowania, które najczęściej powodują przesunięcie układu wydarzenia:

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

Ten typ zmiany jest często spowodowany:

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

zmiany wymiarów elementu;

Taka zmiana ma często następujące przyczyny:

  • Arkusze stylów, które są ładowane późno lub zastępują wcześniej zadeklarowane style.
  • Obrazy i elementy iframe bez atrybutów width i height, które ładują się po ich „boks”, została wyrenderowana.
  • Bloki tekstowe bez atrybutów width lub height, które zamieniają czcionki po renderowaniu tekstu.

wstawianie lub usuwanie elementów DOM;

Zazwyczaj jest to spowodowane:

  • Wstawianie reklam i innych elementów innych firm.
  • Wstawienie banerów, alertów i modałów.
  • Nieskończone przewijanie i inne wzorce UX, które wczytują dodatkowe treści powyżej istniejących treści.

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

Niektóre efekty animacji mogą uruchomić układ. Typowym przykładem jest sytuacja, gdy elementy DOM są „animowane” 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 skorygować przesunięć układu, których nie da się 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 miej otwartą konsolę i używaj interfejsu API niestabilności układu, aby zgłaszać zmiany układu.

Jeśli trudno jest znaleźć zmiany układu, powtórz to ćwiczenie z różne urządzenia i szybkość połączenia. Zwłaszcza użycie wolniejszego co ułatwia identyfikowanie zmian układu. Ponadto: możesz użyć instrukcji debugger, aby ułatwić sobie przejście do układu zmiany.

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ć podczas tworzenia aplikacji, rozważ użycie interfejsu API niestabilności układu w połączeniu z ulubionym narzędziem do rejestrowania danych na poziomie interfejsu użytkownika, aby zebrać więcej informacji o tych problemach. Sprawdź przykład kodu, który pozwala śledzić największy przesunięty element na stronie.