CLS (Cumulative Layout Shift) określa, na ile układ strony „skacze” podczas jej ładowania. Znacie to doświadczenie: macie zamiar kliknąć w przycisk, na górze doładowuje się baner reklamowy, wszystko zjeżdża w dół, klikacie w coś innego. To właśnie zły CLS — a Google karze go od 2021 roku w ramach Core Web Vitals. Progi: ≤ 0,1 = dobry, 0,1–0,25 = do poprawy, > 0,25 = zły (w 75. percentylu).
Obliczenie jest proste do zrozumienia: dla każdego elementu, który porusza się między dwoma klatkami, mnożymy proporcję viewportu objętą zmianą (impact fraction) przez dystans przesunięcia (distance fraction). Sumujemy to przez cały czas życia strony. Typowi winowajcy: (1) obrazy bez podanych wymiarów (`width`/`height`), (2) fonty webowe powodujące FOUT (Flash of Unstyled Text) przy doładowaniu, (3) banery reklamowe lub cookie dorzucane dynamicznie u góry, (4) embedy (Twitter, YouTube) auto-skalujące się, (5) animacje CSS na właściwościach non-composite.
Poprawki są zwykle szybkie — załatwiamy je w kilka godzin podczas bezpłatnego audytu. Po stronie kodu: zawsze deklarować `width` i `height` na obrazach (lub używać komponentu Image z Next.js, który robi to za nas), używać `font-display: optional` lub poprawnie skonfigurowanych fallbacków, rezerwować przestrzeń dla reklam/embedów placeholderem właściwej wielkości, animować wyłącznie `transform` i `opacity`. CLS jest najłatwiejszym z trzech Core Web Vitals do naprawy — gdy świeci się na czerwono, znaczy to po prostu, że frontowi brakuje rygoru. Naprawiamy go na wszystkich naszych stronach na zamówienie.
4 główne przyczyny złego CLS
- Obrazy bez wymiarów: zawsze `width`/`height` (lub `aspect-ratio`) — to 80% przypadków w praktyce.
- Źle skonfigurowane fonty webowe: `font-display: optional` lub fallback z `size-adjust`, by uniknąć skoku przy swapie.
- Reklamy/cookie dynamicznie na górze: rezerwować stały kontener lub wyświetlać na dole/sticky.
- Animacje CSS non-composite: animować `transform`/`opacity` zamiast `top`/`left`/`width`/`height`.
