Jak naprawić problemy ze skumulowanym przesunięciem układu (CLS)
Opublikowany: 2022-03-10Cumulative Layout Shift (CLS) próbuje mierzyć te wstrząsające ruchy strony, ponieważ nowa treść — czy to obrazy, reklamy, czy cokolwiek — pojawia się później niż reszta strony. Oblicza wynik na podstawie tego, jaka część strony nieoczekiwanie się porusza i jak często. Te zmiany treści są bardzo irytujące, powodując, że tracisz miejsce w artykule, który zacząłeś czytać lub, co gorsza, powodujesz, że klikasz niewłaściwy przycisk!
W tym artykule omówię niektóre wzorce frontonu, aby zredukować CLS . Nie będę mówił zbyt wiele o pomiarach CLS, ponieważ omówiłem to już w poprzednim artykule. Nie będę też mówić zbyt wiele o mechanice obliczania CLS: Google ma dobrą dokumentację na ten temat, a The Prawie kompletny przewodnik po skumulowanej zmianie układu Jess Peck jest niesamowitym, głębokim zanurzeniem się w tym. Jednak podam trochę tła potrzebnego do zrozumienia niektórych technik.
Dlaczego CLS jest inny
CLS jest moim zdaniem najbardziej interesującym z kluczowych wskaźników sieciowych, po części dlatego, że jest to coś, czego nigdy wcześniej tak naprawdę nie mierzyliśmy ani nie optymalizowaliśmy. Tak więc próba optymalizacji często wymaga nowych technik i sposobów myślenia. To zupełnie inna bestia niż pozostałe dwa kluczowe wskaźniki internetowe.
Przyglądając się pokrótce pozostałym dwóm podstawowym wskaźnikom internetowym, Największe malowanie treści (LCP) działa dokładnie tak, jak sugeruje jego nazwa i jest bardziej odchyleniem od poprzednich wskaźników ładowania, które mierzą, jak szybko ładuje się strona. Tak, zmieniliśmy sposób, w jaki definiujemy sposób wczytywania strony przez użytkownika, aby przyjrzeć się szybkości wczytywania najtrafniejszej treści , ale zasadniczo ponownie wykorzystujemy stare techniki, aby zapewnić, że treść wczytuje się tak szybko, jak to możliwe. Jak zoptymalizować LCP powinien być stosunkowo dobrze zrozumiałym problemem dla większości stron internetowych.
Opóźnienie pierwszego wejścia (FID) mierzy wszelkie opóźnienia w interakcjach i wydaje się, że nie stanowi problemu dla większości witryn. Optymalizacja, która zwykle polega na oczyszczeniu (lub zmniejszeniu!) JavaScriptu i jest zwykle specyficzna dla witryny. Nie oznacza to, że rozwiązywanie problemów z tymi dwoma wskaźnikami jest łatwe, ale są to dość dobrze zrozumiałe problemy.
Jednym z powodów, dla których CLS jest inny, jest to, że jest mierzony przez czas życia strony — to „skumulowana” część nazwy! Pozostałe dwa kluczowe wskaźniki internetowe zatrzymują się po znalezieniu głównego komponentu na stronie po załadowaniu (dla LCP) lub po pierwszej interakcji (dla FID). Oznacza to, że nasze tradycyjne narzędzia laboratoryjne, takie jak Lighthouse, często nie odzwierciedlają w pełni CLS, ponieważ obliczają tylko początkowe obciążenie CLS. W prawdziwym życiu użytkownik przewinie stronę w dół i może spowodować upuszczenie większej ilości treści, co spowoduje więcej zmian.
CLS to także trochę sztuczna liczba, która jest obliczana na podstawie tego, jaka część strony się porusza i jak często. Podczas gdy LCP i FID są mierzone w milisekundach, CLS jest niemianowaną liczbą wyjściową wynikającą ze złożonych obliczeń. Chcemy, aby strona miała rozmiar 0,1 lub mniej, aby przejść ten kluczowy klucz internetowy. Wszystko powyżej 0,25 jest postrzegane jako „słabe”.
Przesunięcia spowodowane interakcją użytkownika nie są liczone . Jest to definiowane jako w ciągu 500 ms od określonego zestawu interakcji użytkownika, chociaż zdarzenia wskaźnika i przewijanie są wykluczone. Zakłada się, że użytkownik klikający przycisk może spodziewać się pojawienia się treści, na przykład poprzez rozwinięcie zwiniętej sekcji.
CLS polega na mierzeniu nieoczekiwanych zmian . Przewijanie nie powinno powodować przemieszczania się treści, jeśli strona jest zbudowana optymalnie, i podobnie najechanie kursorem na obraz produktu, aby na przykład uzyskać powiększoną wersję, nie powinno również powodować przeskakiwania innych treści. Ale są oczywiście wyjątki i te strony muszą zastanowić się, jak na to zareagować.
CLS stale ewoluuje dzięki poprawkom i poprawkom błędów. Właśnie ogłoszono większą zmianę, która powinna dać wytchnienie długowiecznym stronom, takim jak aplikacje Single Page Apps (SPA) i strony z nieskończonym przewijaniem, które zdaniem wielu były niesprawiedliwie karane w CLS. Zamiast akumulować przesunięcia w ciągu całego czasu strony w celu obliczenia wyniku CLS, tak jak miało to miejsce do tej pory, wynik zostanie obliczony na podstawie największego zestawu przesunięć w określonym przedziale czasowym.
Oznacza to, że jeśli masz trzy kawałki CLS o wartości 0,05, 0,06 i 0,04, to wcześniej zostałoby to zapisane jako 0,15 (tj. powyżej „dobrego” limitu 0,1), podczas gdy teraz zostanie to ocenione jako 0,06. Nadal ma charakter kumulacyjny w tym sensie, że wynik może składać się z oddzielnych przesunięć w tym przedziale czasowym (tj. jeśli ten wynik 0,06 CLS był spowodowany trzema oddzielnymi przesunięciami o 0,02), ale po prostu nie kumuluje się już w całym okresie życia strony .
Mówiąc, że jeśli rozwiążesz przyczyny tej zmiany o 0,06, Twój CLS zostanie zgłoszony jako następny co do wielkości (0,05), więc nadal będzie uwzględniał wszystkie zmiany w okresie istnienia strony — po prostu wybiera raportowanie tylko największy jako wynik CLS.
Po tym krótkim wprowadzeniu do niektórych metodologii CLS przejdźmy do niektórych rozwiązań ! Wszystkie te techniki zasadniczo polegają na zarezerwowaniu odpowiedniej ilości miejsca przed załadowaniem dodatkowej zawartości — niezależnie od tego, czy jest to zawartość multimedialna, czy wstrzyknięta JavaScript, ale twórcy stron internetowych mają do dyspozycji kilka różnych opcji, aby to zrobić.
Ustaw szerokość i wysokość obrazów i ramek iFrames
Pisałem o tym wcześniej, ale jedną z najłatwiejszych rzeczy, które możesz zrobić, aby zmniejszyć CLS, jest upewnienie się, że masz ustawione atrybuty width
i height
na swoich obrazach . Bez nich obraz spowoduje przesunięcie kolejnych treści, aby zrobić dla niego miejsce po pobraniu:
Jest to po prostu kwestia zmiany znaczników obrazu z:
<img src="hero_image.jpg" alt="...">
W celu:
<img src="hero_image.jpg" alt="..." width="400" height="400">
Możesz znaleźć wymiary obrazu, otwierając DevTools i najeżdżając na element (lub dotykając go).
Radzę użyć rozmiaru wewnętrznego (który jest rzeczywistym rozmiarem źródła obrazu), a przeglądarka przeskaluje je do renderowanego rozmiaru, gdy użyjesz CSS do ich zmiany.
Szybka wskazówka : Jeśli, tak jak ja, nie pamiętasz, czy jest to szerokość i wysokość, czy wysokość i szerokość, pomyśl o tym jako o współrzędnych X i Y, więc podobnie jak X, szerokość jest zawsze podawana jako pierwsza.
Jeśli masz responsywne obrazy i używasz CSS do zmiany wymiarów obrazu (np. aby ograniczyć go do max-width
równej 100% rozmiaru ekranu), wtedy te atrybuty mogą zostać użyte do obliczenia height
— pod warunkiem, że pamiętasz o zastąpieniu tego auto
w Twoim CSS:
img { max-width: 100%; height: auto; }
Wszystkie nowoczesne przeglądarki obsługują to teraz, choć nie było to do niedawna opisane w moim artykule. Działa to również w przypadku elementów <picture>
i obrazów srcset
(ustaw width
i height
w zastępczym elemencie img
), ale jeszcze nie w przypadku obrazów o różnych proporcjach — nad tym trwają prace i do tego czasu należy nadal ustawiać width
i height
ponieważ wszystkie wartości będą lepsze niż domyślne 0
na 0
!
Działa to również w przypadku natywnych, leniwych ładowanych obrazów (chociaż Safari domyślnie nie obsługuje natywnego leniwego ładowania).
Nowa właściwość CSS aspect-ratio
Powyższą technikę width
i height
, aby obliczyć wysokość responsywnych obrazów, można uogólnić na inne elementy za pomocą nowej właściwości aspect-ratio
CSS, która jest teraz obsługiwana przez przeglądarki oparte na Chromium i Firefox, ale jest również dostępna w Safari Technology Preview, więc miejmy nadzieję, że wkrótce pojawi się w stabilnej wersji.
Możesz więc użyć go na osadzonym filmie, na przykład w proporcjach 16:9:
video { max-width: 100%; height: auto; aspect-ratio: 16 / 9; }
<video controls width="1600" height="900" poster="..."> <source src="/media/video.webm" type="video/webm"> <source src="/media/video.mp4" type="video/mp4"> Sorry, your browser doesn't support embedded videos. </video>
Co ciekawe, bez definiowania właściwości aspect-ratio
, przeglądarki ignorują wysokość responsywnych elementów wideo i używają domyślnego współczynnika proporcji 2:1, więc powyższe jest potrzebne, aby uniknąć przesunięcia układu w tym miejscu.
W przyszłości powinno być nawet możliwe ustawianie aspect-ratio
dynamicznie w oparciu o atrybuty elementu za pomocą aspect-ratio: attr(width) / attr(height);
ale niestety nie jest to jeszcze obsługiwane.
Lub możesz nawet użyć aspect-ratio
na elemencie <div>
dla pewnego rodzaju niestandardowej kontrolki, którą tworzysz, aby był responsywny:
#my-square-custom-control { max-width: 100%; height: auto; width: 500px; aspect-ratio: 1; }
<div></div>
W przypadku przeglądarek, które nie obsługują aspect-ratio
, można użyć starszego hackowania z dolnym dopełnieniem, ale dzięki prostocie nowszego aspect-ratio
i szerokiej obsłudze (zwłaszcza po przejściu z Safari Technical Preview do zwykłego Safari) jest to trudno uzasadnić tę starszą metodę.
Chrome jest jedyną przeglądarką, która przesyła zwrotnie CLS do Google i obsługuje aspect-ratio
, co oznacza, że rozwiąże Twoje problemy z CLS pod względem kluczowych wskaźników internetowych. Nie lubię przedkładać metryk nad użytkowników, ale fakt, że mają to inne przeglądarki Chromium i Firefox, a Safari, miejmy nadzieję wkrótce, i że jest to postępujące ulepszenie, oznacza, że powiedziałbym, że jesteśmy w punkcie, w którym może zostawić padding-bottom hack i napisać czystszy kod.
Korzystaj z min-height
sposób liberalny
W przypadku elementów, które nie wymagają elastycznego rozmiaru, ale stałej wysokości, rozważ użycie min-height
. Może to dotyczyć na przykład nagłówka o stałej wysokości i możemy mieć różne nagłówki dla różnych punktów przerwania przy użyciu zapytań o media, jak zwykle:
header { min-height: 50px; } @media (min-width: 600px) { header { min-height: 200px; } }
<header> ... </header>
Oczywiście to samo dotyczy min-width
dla elementów umieszczonych poziomo, ale zwykle to wysokość powoduje problemy z CLS.
Bardziej zaawansowaną techniką wstrzykiwania treści i zaawansowanych selektorów CSS jest kierowanie, gdy oczekiwana treść nie została jeszcze wstawiona. Na przykład, jeśli masz następującą zawartość:
<div class="container"> <div class="main-content">...</div> </div>
A dodatkowy div
jest wstawiany przez JavaScript:
<div class="container"> <div class="additional-content">.../div> <div class="main-content">...</div> </div>
Następnie możesz użyć poniższego fragmentu kodu, aby zostawić miejsce na dodatkową zawartość podczas początkowego renderowania elementu div main-content
.
.main-content:first-child { margin-top: 20px; }
Ten kod w rzeczywistości spowoduje przesunięcie do elementu main-content
, ponieważ margines jest liczony jako część tego elementu, więc będzie wyglądał na przesunięcie po jego usunięciu (nawet jeśli w rzeczywistości nie porusza się na ekranie). Jednak przynajmniej zawartość pod nim nie zostanie przesunięta, więc powinno zmniejszyć CLS.
Alternatywnie możesz użyć pseudoelementu ::before
, aby dodać spację, aby uniknąć przesunięcia również w elemencie main-content
:
.main-content:first-child::before { content: ''; min-height: 20px; display: block; }
Ale szczerze mówiąc, lepszym rozwiązaniem jest posiadanie div
w kodzie HTML i wykorzystanie na nim min-height
.
Sprawdź elementy zastępcze
Lubię używać progresywnego ulepszania, aby zapewnić podstawową stronę internetową, nawet bez JavaScript, jeśli to możliwe. Niestety, ostatnio przyłapało mnie to na jednej stronie, którą prowadzę, gdy awaryjna wersja nie-JavaScript była inna niż w momencie uruchomienia JavaScript.
Problem był spowodowany przyciskiem menu „Spis treści” w nagłówku. Zanim uruchomi się JavaScript, jest to proste łącze, stylizowane na przycisk, który przeniesie Cię do strony ze spisem treści. Po uruchomieniu JavaScript staje się dynamicznym menu , które umożliwia bezpośrednie przejście do dowolnej strony, na którą chcesz przejść z tej strony.
Użyłem elementów semantycznych, a więc użyłem elementu kotwicy ( <a href="#table-of-contents">
) dla łącza zastępczego, ale zastąpiłem go <button>
dla dynamicznego menu sterowanego JavaScript. Były one stylizowane tak, aby wyglądały tak samo, ale link zastępczy był o kilka pikseli mniejszy niż przycisk!
To było tak małe, a JavaScript zwykle uruchamiał się tak szybko, że nie zauważyłem, że jest wyłączony. Jednak Chrome zauważył to podczas obliczania CLS i, ponieważ było to w nagłówku, przesunął całą stronę w dół o kilka pikseli. Miało to więc spory wpływ na wynik CLS — wystarczająco, aby umieścić wszystkie nasze strony w kategorii „Potrzeby poprawy”.
To był błąd z mojej strony, a naprawa polegała po prostu na zsynchronizowaniu dwóch elementów (można to również naprawić, ustawiając min-height
nagłówka, jak omówiono powyżej), ale trochę mnie to zdezorientowało. Jestem pewien, że nie tylko ja popełniłem ten błąd, więc bądź świadomy tego, jak strona renderuje się bez JavaScript. Nie sądzisz, że Twoi użytkownicy wyłączają JavaScript? Wszyscy Twoi użytkownicy nie korzystają z JS, gdy pobierają Twój JS.
Czcionki internetowe powodują zmiany układu
Czcionki internetowe są kolejną częstą przyczyną CLS, ponieważ przeglądarka początkowo oblicza potrzebną przestrzeń na podstawie czcionki zastępczej, a następnie ponownie ją oblicza po pobraniu czcionki internetowej. Zwykle CLS jest mały, pod warunkiem, że używana jest czcionka zastępcza o podobnym rozmiarze, więc często nie powodują one wystarczającego problemu, aby zawieść Core Web Vitals, ale mimo to mogą być irytujące dla użytkowników.
Niestety, nawet wstępne ładowanie czcionek internetowych nie pomoże tutaj, ponieważ chociaż skraca to czas używania czcionek zastępczych (co jest dobre dla wydajności ładowania — LCP), pobranie ich nadal zajmuje trochę czasu , więc zastępcze będą nadal używane przez przeglądarkę w większości przypadków, więc nie unika CLS. Mówiąc to, jeśli wiesz, że czcionka internetowa jest potrzebna na następnej stronie (powiedzmy, że jesteś na stronie logowania i wiesz, że następna strona używa specjalnej czcionki), możesz je wstępnie pobrać.
Aby całkowicie uniknąć zmian układu spowodowanych czcionką , nie moglibyśmy oczywiście w ogóle używać czcionek internetowych — w tym zamiast używania czcionek systemowych lub font-display: optional
, aby ich nie używać, jeśli nie zostaną pobrane na czas do początkowego renderowania. Ale żadne z nich nie jest bardzo satysfakcjonujące, szczerze mówiąc.
Inną opcją jest upewnienie się, że sekcje mają odpowiedni rozmiar (np. z min-height
), więc chociaż tekst w nich może się nieco przesunąć, treść pod nim nie zostanie przesunięta w dół, nawet jeśli tak się stanie. Na przykład ustawienie min-height
w elemencie <h1>
może zapobiec przesuwaniu się całego artykułu w dół w przypadku załadowania nieco wyższych czcionek — pod warunkiem, że różne czcionki nie powodują różnej liczby wierszy. Zmniejszy to wpływ przesunięć, jednak w wielu przypadkach użycia (np. akapity ogólne) trudno będzie uogólnić wysokość minimalną.
Najbardziej podekscytowany rozwiązaniem tego problemu są nowe deskryptory czcionek CSS, które umożliwiają łatwiejsze dostosowywanie czcionek zastępczych w CSS:
@font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }
Wcześniej dostosowanie czcionki rezerwowej wymaganej za pomocą interfejsu API ładowania czcionek w JavaScript było bardziej skomplikowane, ale ta opcja, która ma się wkrótce pojawić, może w końcu dać nam łatwiejsze rozwiązanie, które z większym prawdopodobieństwem przyciągnie uwagę. Zobacz mój poprzedni artykuł na ten temat, aby uzyskać więcej informacji na temat nadchodzącej innowacji i więcej zasobów na ten temat.
Szablony początkowe dla stron renderowanych po stronie klienta
Wiele stron renderowanych po stronie klienta lub aplikacji jednostronicowych renderuje początkową stronę podstawową tylko przy użyciu kodu HTML i CSS, a następnie „uwadnia” szablon po pobraniu i wykonaniu kodu JavaScript.
Te początkowe szablony mogą łatwo stracić synchronizację z wersją JavaScript, ponieważ nowe komponenty i funkcje są dodawane do aplikacji w JavaScript, ale nie są dodawane do początkowego szablonu HTML, który jest renderowany jako pierwszy. Powoduje to następnie CLS, gdy te komponenty są wstrzykiwane przez JavaScript.
Przejrzyj więc wszystkie początkowe szablony, aby upewnić się, że nadal są dobrymi początkowymi symbolami zastępczymi. A jeśli początkowy szablon składa się z pustych elementów <div>
, użyj powyższych technik, aby upewnić się, że mają odpowiedni rozmiar, aby uniknąć jakichkolwiek przesunięć.
Ponadto początkowy element div
, który jest wstrzykiwany z aplikacją, powinien mieć min-height
, aby uniknąć renderowania z wysokością 0 na początku przed wstawieniem początkowego szablonu.
<div></div>
Tak długo, jak min-height
jest większa niż większość widocznych obszarów , powinno to na przykład unikać CLS w stopce witryny. CLS jest mierzony tylko wtedy, gdy znajduje się w widocznym obszarze, a więc wpływa na użytkownika. Domyślnie pusty element div
ma wysokość 0 pikseli, więc nadaj mu min-height
, która jest bliższa rzeczywistej wysokości po załadowaniu aplikacji.
Zapewnij zakończenie interakcji użytkownika w ciągu 500 ms
Interakcje użytkownika, które powodują przesunięcie treści, są wykluczone z wyników CLS. Są one ograniczone do 500 ms po interakcji. Jeśli więc klikniesz przycisk i wykonasz złożone przetwarzanie, które trwa ponad 500 ms, a następnie wyrenderujesz nową zawartość, Twój wynik CLS ucierpi.
Możesz sprawdzić, czy przesunięcie zostało wykluczone w Chrome DevTools , używając karty Wydajność, aby zarejestrować stronę, a następnie znajdując przesunięcia, jak pokazano na następnym zrzucie ekranu. Otwórz DevTools, przejdź do bardzo zastraszającej (ale bardzo przydatnej, gdy już to zrozumiesz!) karty Wydajność , a następnie kliknij przycisk nagrywania w lewym górnym rogu (zakreślony na obrazku poniżej) i wejdź w interakcję ze swoją stroną i zatrzymaj nagrywanie raz kompletny.
Zobaczysz taśmę filmową strony, na której załadowałem niektóre komentarze do innego artykułu w Smashing Magazine, więc w części, którą zakreśliłem, możesz prawie zauważyć wczytywanie komentarzy i czerwoną stopkę przesuniętą poza ekran. W dalszej części karty Wydajność , pod linią Doświadczenie , Chrome umieści czerwonawo-różowawe pole dla każdej zmiany, a po kliknięciu otrzymasz więcej szczegółów na karcie Podsumowanie poniżej.
Tutaj widać, że uzyskaliśmy ogromny wynik 0,3359 — znacznie powyżej progu 0,1, do którego dążymy, ale wynik skumulowany tego nie uwzględnił, ponieważ Ostatnie dane wejściowe są ustawione na Zastosowania.
Zapewnienie, że interakcje tylko przesuwają zawartość w ciągu 500 ms, graniczy z tym, co próbuje zmierzyć opóźnienie pierwszego wejścia, ale zdarzają się przypadki, w których użytkownik może zobaczyć, że dane wejściowe przyniosły efekt (np. pokazano pokrętło ładowania), więc FID jest dobry, ale treść może nie zostanie dodany do strony przed upływem limitu 500 ms, więc CLS jest zły.
Najlepiej byłoby, gdyby cała interakcja zakończyła się w ciągu 500 ms, ale możesz zrobić kilka rzeczy, aby wygospodarować niezbędną przestrzeń, korzystając z powyższych technik, podczas gdy przetwarzanie jest w toku, więc jeśli zajmie to więcej niż magiczne 500 ms, to masz już obsługiwał zmianę, więc nie zostanie za to ukarany. Jest to szczególnie przydatne podczas pobierania treści z sieci, które mogą być zmienne i pozostawać poza Twoją kontrolą.
Inne elementy, na które należy uważać, to animacje , które trwają dłużej niż 500 ms, a więc mogą wpływać na CLS. Chociaż może się to wydawać nieco restrykcyjne, celem CLS nie jest ograniczenie „zabawy”, ale ustalenie rozsądnych oczekiwań dotyczących doświadczenia użytkownika i nie sądzę, aby nierealistyczne było oczekiwanie, że zajmą one 500 ms lub mniej. Ale jeśli się nie zgadzasz lub masz przypadek użycia, którego mogli nie wziąć pod uwagę, zespół Chrome jest otwarty na opinie na ten temat.
Synchroniczny JavaScript
Ostatnia technika, którą zamierzam omówić, jest nieco kontrowersyjna, ponieważ jest sprzeczna z dobrze znanymi poradami dotyczącymi wydajności sieci, ale może być jedyną metodą w pewnych sytuacjach. Zasadniczo, jeśli masz zawartość, o której wiesz, że spowoduje przesunięcia, jednym z rozwiązań pozwalających ich uniknąć jest nie renderowanie jej, dopóki się nie uspokoi!
Poniższy kod HTML początkowo ukryje div
, a następnie załaduje kod JavaScript blokujący renderowanie, aby wypełnić div
, a następnie go odkryje. Ponieważ JavaScript blokuje renderowanie, nic poniżej tego nie zostanie wyrenderowane (włącznie z drugim blokiem style
do odkrycia go), a więc nie nastąpią żadne przesunięcia.
<style> .cls-inducing-div { display: none; } </style> <div class="cls-inducing-div"></div> <script> ... </script> <style> .cls-inducing-div { display: block; } </style>
Ważne jest, aby za pomocą tej techniki wstawić CSS w HTML , więc jest on stosowany w kolejności. Alternatywą jest odkrycie treści za pomocą samego JavaScript, ale w powyższej technice podoba mi się to, że nadal odkrywa zawartość, nawet jeśli JavaScript zawiedzie lub zostanie wyłączony przez przeglądarkę.
Ta technika może być nawet zastosowana z zewnętrznym JavaScriptem, ale spowoduje to większe opóźnienie niż script
wbudowany, ponieważ zewnętrzny JavaScript jest wymagany i pobierany. To opóźnienie można zminimalizować, wstępnie ładując zasób JavaScript, aby był dostępny szybciej, gdy parser dotrze do tej sekcji kodu:
<head> ... <link rel="preload" href="cls-inducing-javascript.js" as="script"> ... </head> <body> ... <style> .cls-inducing-div { display: none; } </style> <div class="cls-inducing-div"></div> <script src="cls-inducing-javascript.js"></script> <style> .cls-inducing-div { display: block; } </style> ... </body>
Teraz, jak powiedziałem, jestem pewien, że sprawi to, że niektórzy ludzie z wydajnością sieciową będą się niepokoić, ponieważ rada jest taka, aby używać async, defer
lub nowszego type="module"
(które są domyślnie defer
) w JavaScript specjalnie, aby uniknąć blokowania render , podczas gdy my tutaj robimy odwrotnie! Jeśli jednak treści nie można z góry określić i spowoduje to wstrząsające zmiany, nie ma sensu renderować jej wcześnie.
Użyłem tej techniki do banera cookie , który ładował się u góry strony i przesuwał zawartość w dół:
Wymagało to odczytania pliku cookie, aby sprawdzić, czy wyświetlić baner pliku cookie, czy nie, i chociaż można to wykonać po stronie serwera, była to statyczna witryna bez możliwości dynamicznej zmiany zwróconego kodu HTML.
Banery cookie można zaimplementować na różne sposoby, aby uniknąć CLS. Na przykład umieszczając je na dole strony lub nakładając je na wierzch treści, zamiast przesuwać treść w dół. Woleliśmy, aby treść była u góry strony, więc musieliśmy użyć tej techniki, aby uniknąć przesunięć. Istnieje wiele innych alertów i banerów, które właściciele witryn mogą preferować u góry strony z różnych powodów.
Użyłem tej techniki również na innej stronie, na której JavaScript przenosi zawartość do kolumn „main” i „side” (z powodów, o których nie będę się wdawał, nie było możliwości poprawnego skonstruowania tego po stronie serwera HTML). Ponowne ukrywanie treści, dopóki JavaScript nie zmienił jej kolejności, a dopiero potem ją pokazał, pozwoliło uniknąć problemów z CLS, które obniżały wynik CLS tych stron. I znowu zawartość jest automatycznie odkrywana, nawet jeśli JavaScript z jakiegoś powodu nie działa i wyświetlana jest niezmieniona zawartość.
Korzystanie z tej techniki może wpłynąć na inne metryki (w szczególności LCP, a także Pierwsze wyrenderowanie treści), ponieważ opóźniasz renderowanie, a także potencjalnie blokujesz preloader z wyprzedzeniem w przeglądarkach, ale jest to kolejne narzędzie do rozważenia w przypadkach, w których nie ma innej opcji.
Wniosek
Skumulowane przesunięcie układu jest spowodowane zmianą wymiarów treści lub wstrzyknięciem nowej treści na stronę przez późno uruchomiony kod JavaScript. W tym poście omówiliśmy różne wskazówki i triki, aby tego uniknąć. Cieszę się, że światło reflektorów Core Web Vitals zajaśniało na tym irytującym problemie — zbyt długo my, twórcy stron internetowych (i zdecydowanie zaliczam do tego siebie) ignorowaliśmy ten problem.
Uporządkowanie moich własnych stron internetowych zapewniło wszystkim odwiedzającym lepsze wrażenia. Zachęcam do przyjrzenia się również swoim problemom z CLS i mam nadzieję, że niektóre z tych wskazówek będą przydatne, gdy to zrobisz. Kto wie, może uda Ci się nawet zejść do nieuchwytnego wyniku 0 CLS dla wszystkich Twoich stron!
Więcej zasobów
- Artykuły Core Web Vitals na Smashing Magazine, w tym moje własne na temat ustawiania szerokości i wysokości obrazów, mierzenia podstawowych wskaźników internetowych i deskryptorów czcionek CSS.
- Dokumentacja Google Core Web Vitals, w tym ich strona w CLS.
- Więcej szczegółów na temat ostatniej zmiany w CLS, a następnie ta zmiana zaczęła być aktualizowana w różnych narzędziach Google.
- Dziennik zmian CLS szczegółowo opisujący zmiany w każdej wersji Chrome.
- Prawie kompletny przewodnik po skumulowanej zmianie układu autorstwa Jess Peck.
- Kumulatywne przesunięcie układu: Mierz i unikaj niestabilności wizualnej, Karolina Szczur.
- Generator GIFów z przesunięciem układu, który pomaga w generowaniu demonstracji CLS, które można udostępniać.