CLS-optimering i 2026: Din komplette guide til Cumulative Layout Shift
Du kender sikkert følelsen. Du sidder og læser en artikel på telefonen, og pludselig hopper hele teksten ned, fordi en reklame eller et billede indlæses. Eller — og det her er næsten værre — du er ved at trykke på en knap, men i det øjeblik du rører skærmen, flytter indholdet sig, og du ender med at klikke på noget helt andet. Frustrerende? Ja, helt vildt. Og det er præcis den slags oplevelser, som Cumulative Layout Shift (CLS) måler.
I vores tidligere artikler har vi dykket ned i INP og LCP — responsivitet og indlæsningshastighed. Nu er det tid til den tredje og sidste Core Web Vital: visuelt stabilitet.
CLS er lidt paradoksal. Det er den metrik, som flest websites faktisk består — ifølge CrUX-data fra februar 2026 har over 85 % af alle websites en god CLS-score. Men når den fejler? Så er det typisk med ret katastrofale konsekvenser for brugeroplevelsen og konverteringsraten.
I denne guide dækker vi alt om CLS i 2026: beregningsmetoden, tærskelværdier, avancerede debugging-teknikker og de nyeste optimeringsstrategier (herunder CSS Containment og den nye Layout Shift Culprits-funktion i Chrome DevTools).
Hvad er Cumulative Layout Shift?
Cumulative Layout Shift er en Core Web Vital-metrik, der kvantificerer den visuelle ustabilitet på en webside. Et layout shift opstår, når et synligt element ændrer sin position mellem to renderede frames — uden at det er udløst af en brugerinteraktion. CLS måler den samlede sum af disse uventede forskydninger gennem hele sidens levetid.
Nøgleordet her er uventede.
Hvis en bruger klikker på en accordion, der folder sig ud og skubber indhold ned, er det helt forventet og tæller ikke med. Browserens regel er faktisk ret simpel: Hvis et layout shift sker inden for 500 millisekunder efter en brugerinteraktion (klik, tryk, tastaturinput), undtages det fra CLS-beregningen.
Sådan beregnes CLS-scoren
Hvert individuelt layout shift beregnes ud fra to faktorer:
- Impact Fraction (Påvirkningsbrøkdel): Hvor stor en del af viewporten, der påvirkes af forskydningen. Hvis et element fylder 25 % af viewporten og flytter sig, så det samlet påvirker 50 % af viewport-arealet (sin gamle position plus sin nye), er impact fraction 0,5.
- Distance Fraction (Afstandsbrøkdel): Hvor langt det mest forskudte element har bevæget sig, målt som en andel af viewporten. Et element der flytter sig 150 pixels i en viewport på 800 pixels giver en distance fraction på 150/800 = 0,1875.
Den endelige score for ét enkelt layout shift er:
Layout shift score = Impact Fraction × Distance Fraction
I eksemplet ovenfor: 0,5 × 0,1875 = 0,09375. Ikke super intuitivt, men det virker i praksis.
CLS bruger et session window-koncept til at gruppere relaterede shifts. Et session window er en periode med layout shifts, hvor der maksimalt er 1 sekund mellem hvert shift, og det samlede vindue varer højst 5 sekunder. Den vigtige detalje: CLS-scoren for en side er den højeste samlede score blandt alle session windows — ikke summen af alle shifts på hele siden.
CLS-tærskelværdier
Google definerer tre kategorier for CLS-scores, målt på 75. percentil af alle sidebesøg:
- God (Good): Under 0,1 — siden føles visuelt stabil, og brugeren mærker ingen uventede forskydninger.
- Behøver forbedring (Needs Improvement): Mellem 0,1 og 0,25 — brugeren oplever lejlighedsvis synlige spring i layoutet.
- Dårlig (Poor): Over 0,25 — indholdet hopper markant rundt og forstyrrer brugerens læsning eller interaktion.
CLS er den eneste Core Web Vital uden en tidsenhed — den er et dimensionsløst tal. Min anbefaling er at sigte efter en CLS under 0,05 for at have lidt sikkerhedsmargin. Flere brancheanalyser fra 2026 peger på, at en CLS under 0,05 korrelerer med markant bedre engagement-metrics, og der er gode grunde til at forvente, at Google vil stramme den officielle tærskelværdi på et tidspunkt.
De seks mest almindelige årsager til CLS
Før du kan fikse CLS, skal du forstå hvad der typisk forårsager det. Her er de hyppigste syndere, rangeret efter hvor ofte de optræder i praksis.
1. Billeder og videoer uden dimensioner
Den mest klassiske CLS-årsag — og heldigvis også den nemmeste at fikse.
Når browseren parser et <img>-tag uden width- og height-attributter, aner den ikke hvor meget plads billedet skal fylde. Den renderer siden som om billedet har nul højde. Når billedet så indlæses, springer alt indhold nedenunder ned for at gøre plads.
<!-- Dårligt: Ingen dimensioner, forårsager CLS -->
<img src="/images/produkt.webp" alt="Produktbillede">
<!-- Godt: Dimensioner angivet, browseren reserverer plads -->
<img
src="/images/produkt.webp"
alt="Produktbillede"
width="800"
height="600"
>
<!-- Endnu bedre: Responsive med aspect-ratio -->
<img
src="/images/produkt.webp"
alt="Produktbillede"
width="800"
height="600"
style="width: 100%; height: auto; aspect-ratio: 4/3;"
>
En ting der forvirrer mange: width- og height-attributterne i HTML styrer ikke den visuelle størrelse (det gør CSS). De giver browseren et aspect ratio, så den kan reservere den korrekte plads. Moderne browsere bruger automatisk disse attributter til at beregne et implicit aspect-ratio, selv med responsiv CSS.
2. Webfonts der forårsager tekst-reflow
Webfonts er en tavs CLS-dræber, og den er overraskende nem at overse.
Når en side indlæses, vises teksten enten med en fallback-font (FOUT — Flash of Unstyled Text) eller slet ikke (FOIT — Flash of Invisible Text). Når den rigtige font endelig indlæses, kan teksten ændre bredde og højde, fordi den nye font har andre metriker. Og det udløser et layout shift.
/* Strategi 1: font-display: swap med matchende fallback */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap;
}
/* Brug size-adjust til at matche fallback-fontens metriker */
@font-face {
font-family: 'CustomFont-Fallback';
src: local('Arial');
size-adjust: 105%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: 'CustomFont', 'CustomFont-Fallback', Arial, sans-serif;
}
/* Strategi 2: font-display: optional eliminerer CLS helt */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: optional;
}
Den bedste kombination er font-display: optional med <link rel="preload">. Med optional vises fallback-fonten, hvis den rigtige font ikke er klar inden for ca. 100ms. Der sker ingen font-swap bagefter — og dermed ingen layout shift. Simpelt og effektivt.
<!-- Preload kritiske fonts i <head> -->
<link
rel="preload"
href="/fonts/custom.woff2"
as="font"
type="font/woff2"
crossorigin
>
3. Reklamer, embeds og iframes uden reserveret plads
Tredjepartsreklamer er nok den mest frustrerende CLS-kilde at arbejde med. De indlæses typisk asynkront, og når de endelig renderer, skubber de alt indhold ned. Og problemet forværres af, at mange reklamenetværk leverer annoncer i varierende størrelser — så du ved ikke engang præcis hvor meget plads du skal reservere.
<!-- Dårligt: Ingen reserveret plads -->
<div id="ad-banner"></div>
<!-- Godt: Reserveret plads med min-height -->
<div id="ad-banner" style="min-height: 250px; min-width: 300px;">
<!-- Reklameindhold indsættes her af ad-scriptet -->
</div>
<!-- Endnu bedre: Container med aspect-ratio og baggrund -->
<div
id="ad-banner"
style="
aspect-ratio: 300/250;
max-width: 300px;
background-color: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
"
>
<span style="color: #999; font-size: 12px;">Annonce</span>
</div>
Et praktisk tip: Hvis dit reklamenetværk leverer annoncer i forskellige størrelser (f.eks. 300×250 eller 320×100), så reserver plads til den størrelse der forekommer oftest. Alternativt kan du bruge en min-height svarende til det største mulige annonceformat. Det er ikke perfekt, men det er langt bedre end ingenting.
4. Dynamisk indsat indhold via JavaScript
Cookie-bannere, notifikationer, chat-widgets, indholdsanbefalinger — dynamisk indhold der indsættes oven for eksisterende indhold er en klassisk CLS-fælde. Hver gang et nyt element indsættes i DOM'en over synligt indhold, skubbes alt nedenunder ned.
// Dårligt: Indsætter banner øverst og skubber indhold ned
function showCookieBanner() {
const banner = document.createElement('div');
banner.textContent = 'Vi bruger cookies...';
banner.className = 'cookie-banner';
document.body.prepend(banner); // Skubber ALT indhold ned
}
// Godt: Brug en fast container med reserveret plads
// HTML: <div id="cookie-placeholder" style="min-height: 60px;"></div>
function showCookieBanner() {
const placeholder = document.getElementById('cookie-placeholder');
placeholder.innerHTML = '<div class="cookie-banner">Vi bruger cookies...</div>';
}
// Endnu bedre: Fixed/sticky positionering forårsager ikke CLS
function showCookieBanner() {
const banner = document.createElement('div');
banner.textContent = 'Vi bruger cookies...';
banner.style.cssText = 'position: fixed; bottom: 0; width: 100%; z-index: 1000;';
document.body.appendChild(banner);
}
Her er den vigtige indsigt: Elementer med position: fixed eller position: sticky er taget ud af det normale dokumentflow og forårsager derfor ikke layout shifts. Det gør fixed positionering til en fremragende strategi for cookie-bannere, notifikationer og lignende overlays.
5. Animationer der trigger layout
Den her overrasker mange. CSS-animationer kan forårsage CLS, hvis de animerer layout-udløsende egenskaber som width, height, top, left, padding eller margin. Hver animationsframe kan potentielt udløse et layout shift.
/* Dårligt: Animerer layout-egenskaber — forårsager CLS */
.expanding-panel {
transition: height 0.3s ease;
height: 0;
}
.expanding-panel.open {
height: 200px; /* Trigger layout shift for alt nedenunder */
}
/* Godt: Brug transform i stedet — ingen CLS */
.expanding-panel {
transform: scaleY(0);
transform-origin: top;
transition: transform 0.3s ease;
}
.expanding-panel.open {
transform: scaleY(1); /* Ingen layout shift, GPU-accelereret */
}
/* Alternativ: Brug opacity + transform for slide-in-effekt */
.notification {
transform: translateY(-100%);
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.notification.visible {
transform: translateY(0);
opacity: 1;
}
Reglen er simpel nok til at huske: transform og opacity er de eneste CSS-egenskaber du kan animere uden at forårsage layout shifts. De er GPU-accelererede og påvirker ikke andre elementers position. Lær det, og brug det altid.
6. Single Page Apps og klientside navigation
I SPA'er (React, Vue, Angular, Svelte) opstår CLS ofte under route-skift. Når brugeren navigerer til en ny "side", erstatter JavaScript det eksisterende indhold med nyt, og hvis det nye indholds layout afviger fra det gamle, kan der opstå massive layout shifts.
Det er særligt problematisk, fordi Googles crawler nu renderer JavaScript og måler CLS under hele sessionen.
Den vigtigste regel: Hold delte layoutelementer (header, navigation, sidebar) stabile mellem routes. Hvis headeren har én højde på forsiden og en anden på undersider, udløser det CLS ved hvert eneste route-skift.
/* Sørg for, at header har fast højde på tværs af alle routes */
.site-header {
height: 64px; /* Fast højde */
/* Undgå at lade header-højden afhænge af dynamisk indhold */
}
/* Brug min-height på main-content til at undgå
layout shift, når indhold indlæses */
.main-content {
min-height: calc(100vh - 64px);
}
Diagnosticering af CLS-problemer
Okay, du ved nu hvad der forårsager CLS. Men hvordan finder du de specifikke problemer på din side? Her er de vigtigste værktøjer og teknikker i 2026.
Chrome DevTools: Layout Shift Regions
Den hurtigste måde at få et visuelt overblik over layout shifts er at aktivere Layout Shift Regions i Chrome DevTools. Gå til Settings > More Tools > Rendering > Layout Shift Regions, og genindlæs siden. Områder med layout shifts markeres med lilla rektangler, der blinker kortvarigt når forskydningen sker.
Det giver dig et øjeblikkeligt billede af, hvor på siden problemerne opstår. Utroligt nyttigt som første skridt.
Chrome DevTools: Layout Shift Culprits (nyt i 2026)
Det her er ærligt talt et kvantespring fremad for CLS-debugging. Chrome DevTools har i 2026 fået en ny Layout Shift Culprits-funktion i Insights-panelet. Den identificerer ikke bare de elementer der blev forskudt, men forsøger også at finde årsagen til forskydningen.
Det er en vigtig forskel. Lighthouse kan fortælle dig, at et afsnit blev forskudt 150 pixels ned. Layout Shift Culprits kan fortælle dig, at det skyldtes et billede uden dimensioner, der blev indlæst ovenfor. Og det er den information du faktisk har brug for.
Funktionen inkluderer:
- Realtidsvisualisering: Se layout shifts mens de sker under live interaktion med siden.
- Frame-by-frame afspilning: Gennemgå hvert shift trin for trin for at forstå den nøjagtige sekvens.
- Detaljerede metriker: Størrelse, timing og samlet påvirkning for hvert individuelt shift.
Performance Observer API til feltdata
Lab-data er fint til debugging, men du har også brug for data fra dine rigtige brugere. Her kan du bruge Googles web-vitals-bibliotek med attribution build:
import { onCLS } from 'web-vitals/attribution';
onCLS((metric) => {
const { value, rating, entries, attribution } = metric;
// Grundlæggende CLS-data
console.log('CLS:', value);
console.log('Vurdering:', rating); // 'good', 'needs-improvement' eller 'poor'
// Attribution: Hvilket element forårsagede det største shift?
console.log('Største shift-element:', attribution.largestShiftTarget);
console.log('Største shift-værdi:', attribution.largestShiftValue);
console.log('Indlæsningstilstand:', attribution.loadState);
// Detaljer for hvert enkelt layout shift
entries.forEach((entry, i) => {
console.log(`Shift ${i}:`, {
værdi: entry.value,
tidspunkt: entry.startTime,
kilder: entry.sources?.map(source => ({
element: source.node?.nodeName,
forrigePosition: source.previousRect,
nyPosition: source.currentRect
}))
});
});
// Send til analytics
navigator.sendBeacon('/analytics/cls', JSON.stringify({
value,
rating,
largestShiftTarget: attribution.largestShiftTarget,
largestShiftValue: attribution.largestShiftValue,
loadState: attribution.loadState,
url: location.href,
navigationType: metric.navigationType
}));
}, { reportAllChanges: true });
Feltet loadState er særligt nyttigt. Det fortæller dig om layout shiftet skete under indlæsning (loading), efter indlæsning (dom-interactive, dom-content-loaded, complete), eller under en efterfølgende interaktion. Det hjælper enormt med at prioritere — shifts under indlæsning rammer alle brugere, mens post-load shifts kun rammer dem der udfører bestemte handlinger.
Rå PerformanceObserver til detaljeret debugging
Vil du have fuld kontrol over hvilke layout shifts du logger? Så kan du bruge den rå PerformanceObserver API:
// Observer der logger alle layout shifts med detaljerede kilder
const clsObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Spring brugerudløste shifts over
if (entry.hadRecentInput) continue;
console.group(`Layout Shift: ${entry.value.toFixed(4)}`);
console.log('Tidspunkt:', entry.startTime.toFixed(0), 'ms');
// Log hvert forskudt element
if (entry.sources) {
entry.sources.forEach((source, i) => {
console.log(`Kilde ${i}:`, {
element: source.node,
fra: `(${source.previousRect.x}, ${source.previousRect.y})`,
til: `(${source.currentRect.x}, ${source.currentRect.y})`
});
});
}
console.groupEnd();
}
});
clsObserver.observe({ type: 'layout-shift', buffered: true });
Avancerede optimeringsteknikker
Har du styr på de grundlæggende fixes — dimensioner på billeder, reserveret plads til reklamer — så er det tid til de avancerede teknikker, der kan bringe din CLS helt ned mod nul.
CSS Containment til at isolere layout shifts
CSS Containment med contain-egenskaben er efter min mening et af de mest undervurderede værktøjer til CLS-forebyggelse. Idéen er enkel: Du fortæller browseren, at et element er uafhængigt af resten af siden, og så kan du forhindre at layout shifts spreder sig fra en komponent til resten af DOM-træet.
/* contain: content er den sikre standardindstilling.
Den aktiverer layout, paint og style containment
uden at kræve eksplicitte dimensioner. */
.widget-container {
contain: content;
}
/* contain: strict giver maksimal isolering,
men kræver eksplicit width/height. */
.ad-slot {
contain: strict;
width: 300px;
height: 250px;
}
/* Brug contain: layout til at forhindre,
at ændringer inde i en komponent påvirker
elementers position uden for den. */
.card-grid .card {
contain: layout;
}
/* Kombination med content-visibility for off-screen indhold */
.article-section {
contain: content;
content-visibility: auto;
contain-intrinsic-height: auto 500px;
}
Tallene taler for sig selv: I performance-tests kan CSS Containment reducere renderingstid fra over 700ms til under 55ms for komplekse layouts. Browseren kan begrænse sine layout-beregninger til det isolerede element i stedet for at genberegne hele sidens layout.
Kombinationen af content-visibility: auto og contain-intrinsic-height er særligt effektiv for lange sider med mange sektioner. Browseren springer rendering af off-screen sektioner over, men reserverer stadig den korrekte plads, så scrollbaren forbliver stabil. En win-win.
Skeleton screens der matcher det endelige layout
Skeleton screens er et populært UX-mønster, men her er en vigtig advarsel: De kan faktisk forværre CLS, hvis de ikke er implementeret korrekt.
Problemet opstår, når skelettet har en anden højde end det endelige indhold. Så får du bare et layout shift, når det rigtige indhold erstatter skelettet. Det er en klassisk fælde.
/* Skeleton der matcher det endelige layout præcist */
.product-card-skeleton {
/* Brug SAMME dimensioner som den rigtige product-card */
height: 380px; /* Fast højde matcher .product-card */
border-radius: 8px;
overflow: hidden;
}
.product-card-skeleton .image-placeholder {
height: 200px; /* Matcher .product-card img højden */
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
.product-card-skeleton .text-placeholder {
height: 20px;
margin: 12px 16px;
background: #f0f0f0;
border-radius: 4px;
}
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
Princippet er simpelt: Skelettet skal have nøjagtig samme ydre dimensioner som det endelige indhold. Brug samme height, padding, margin og border som den rigtige komponent. Test det i DevTools ved at sammenligne de to.
Bfcache til nul-CLS ved navigation
Back/Forward Cache (bfcache) er ærligt talt en af de mest effektive CLS-teknikker, og den kræver næsten ingen ekstra kode — du skal bare undgå at blokere den.
Når en bruger navigerer væk fra en side og vender tilbage, gendanner bfcache siden præcis som den var — inklusiv scroll-position, formulardata og fuldt renderet layout. Ingen genindlæsning, ingen parsing, og dermed ingen mulighed for layout shifts.
For at sikre at dine sider er bfcache-kompatible, skal du undgå disse fælder:
// Bfcache-blokerende kode — undgå dette:
// 1. unload event handler blokerer bfcache
window.addEventListener('unload', () => {
// Brug IKKE unload — brug pagehide i stedet
});
// 2. Cache-Control: no-store blokerer bfcache
// Undgå denne header for sider, der bør caches
// Bfcache-venlig kode:
// Brug pagehide i stedet for unload
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
// Siden blev lagt i bfcache
console.log('Siden gemmes i bfcache');
}
});
// Gendan tilstand korrekt ved bfcache-restore
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Siden blev gendannet fra bfcache
console.log('Siden gendannet fra bfcache — nul CLS!');
// Opdater eventuel tidsfølsom data her
}
});
Håndtering af lazy-loaded indhold
Lazy loading er fantastisk til performance. Men det kan forårsage CLS, hvis det ikke håndteres rigtigt.
Når et lazy-loaded billede træder ind i viewporten og udvider sig til sin fulde størrelse, skubber det alt indhold nedenunder ned. Heldigvis er løsningen den samme som for normale billeder:
<!-- Korrekt lazy loading uden CLS -->
<img
src="/images/produkt.webp"
alt="Produktbillede"
loading="lazy"
width="800"
height="600"
decoding="async"
>
<!-- width og height sikrer reserveret plads,
selv før billedet indlæses -->
<!-- Vigtigt: Brug IKKE loading="lazy" på LCP-billedet!
Det forsinker indlæsningen af det vigtigste billede. -->
For JavaScript-baserede lazy loading-biblioteker skal du sikre, at containeren har en fast størrelse, inden IntersectionObserver registrerer elementet og starter indlæsningen.
CLS i praksis: En komplet optimerings-tjekliste
Her er en systematisk tjekliste du kan følge for at bringe din CLS-score ned mod nul. De tre første punkter alene løser typisk 80-90 % af alle CLS-problemer:
- Audit med DevTools: Aktiver Layout Shift Regions og brug den nye Layout Shift Culprits-funktion til at identificere alle CLS-kilder.
- Billeder: Tilføj
widthogheighttil alle<img>- og<video>-tags. Brugaspect-ratioi CSS til responsive billeder. - Fonts: Preload kritiske fonts med
<link rel="preload">. Brugfont-display: optionalfor nul-CLS, ellerfont-display: swapmedsize-adjustfor matchende fallback-metriker. - Reklamer og embeds: Reserver plads med
min-heightpå alle reklameslots, iframes og embedded indhold. - Dynamisk indhold: Indsæt aldrig indhold oven for synligt indhold, medmindre det er brugerudløst. Brug
position: fixedtil overlays. - Animationer: Brug kun
transformogopacitytil animationer. Undgå at animereheight,width,top,left,paddingellermargin. - CSS Containment: Tilføj
contain: contenttil uafhængige widgets og sektioner for at isolere layout shifts. - SPA-navigation: Hold delte layout-elementer (header, nav, footer) på en fast størrelse på tværs af alle routes.
- Bfcache: Fjern
unload-listeners ogCache-Control: no-storefor at aktivere bfcache. - Monitorer i produktion: Implementer
web-vitals-bibliotekets attribution build til at tracke CLS fra rigtige brugere.
Ofte stillede spørgsmål om CLS
Hvad er en god CLS-score?
En god CLS-score er under 0,1, målt på 75. percentil af alle sidebesøg. Det betyder, at mindst 75 % af dine besøgende skal have en CLS-oplevelse under 0,1 for at bestå Core Web Vitals-testen. I praksis anbefaler jeg at sigte mod under 0,05 for at have sikkerhedsmargin — enheder og netværksforhold varierer enormt blandt dine brugere.
Hvordan finder jeg ud af, hvad der forårsager CLS på min side?
Start med Chrome DevTools: Aktiver Layout Shift Regions under Rendering for at se visuelle markeringer af shifts. Brug derefter den nye Layout Shift Culprits-funktion i Insights-panelet for at identificere rodårsagen. For feltdata kan du implementere web-vitals/attribution-biblioteket, som fortæller dig præcis hvilket DOM-element der forskubbede, og i hvilken indlæsningstilstand det skete.
Påvirker CLS min Google-rangering?
Ja. CLS er en af de tre Core Web Vitals, som Google bruger som rankingssignal. Sider der består alle tre Core Web Vitals (LCP, INP og CLS) har i gennemsnit 24 % lavere bouncerate og bedre organiske placeringer. CLS har dog den højeste beståelsesrate blandt de tre metriker, så det er sjældent CLS alene der afgør din ranking — men det bidrager til det samlede billede.
Kan CLS opstå efter sideindlæsning?
Ja, absolut. CLS måles gennem hele sidens levetid, ikke kun under den indledende indlæsning. Layout shifts kan opstå når brugeren scroller og lazy-loaded indhold vises, når dynamisk indhold indsættes via JavaScript, ved SPA-navigation, eller når reklamer genindlæses. Disse post-load shifts fanges via session window-mekanismen og tæller fuldt med i din score.
Hvad er forskellen på CLS i Lighthouse og CrUX-feltdata?
Lighthouse måler CLS i et simuleret lab-miljø med en fast indlæsningsperiode. Den fanger typisk kun shifts under den indledende sideindlæsning — ikke post-load shifts fra brugerinteraktioner, lazy loading eller dynamisk indhold. CrUX-feltdata derimod måler CLS fra rigtige brugere over hele sessionens levetid, inklusiv scrolling, klik og navigation. Derfor kan din Lighthouse CLS-score se fin ud, mens dine rigtige brugere oplever dårlig CLS. Min anbefaling: Brug altid feltdata som den endelige sandhed.