Trova e risolvi i problemi di Cumulative Layout Shift (CLS)

Scopri come trovare e risolvere tutti i problemi di Cumulative Layout Shift con i dati RUM, Chrome DevTools e fix CSS e HTML mirati

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-10-26

Trova e risolvi i problemi di Cumulative Layout Shift (CLS)

Questa pagina fa parte della serie sul Cumulative Layout Shift (CLS). Il CLS misura la stabilità visiva della pagina tracciando gli spostamenti imprevisti dei contenuti. Un buon punteggio CLS è inferiore a 0,1, mentre sopra 0,25 è scadente. Se non hai mai lavorato con il CLS, parti dalla pagina hub del CLS per formula, soglie e funzionamento delle session window.

Il CLS è il Core Web Vital con i risultati migliori. Secondo il Web Almanac 2025, il 72% dei siti web nel mondo lo supera. Sembra un ottimo dato, finché non ti rendi conto che quasi nessun developer vede i problemi di CLS sulla propria macchina. Gli spostamenti avvengono per chi visita il sito per la prima volta su connessioni lente. Quando fai un controllo in DevTools con la cache già calda, sembra tutto a posto. Ed è proprio questo che rende il debug del CLS così difficile.

Questa guida si basa esattamente sul processo passo dopo passo che uso nelle consulenze sul CLS: prima i dati CrUX e RUM, poi la verifica in Chrome e infine il fix.

Ultima revisione a cura di Arjen Karel a marzo 2026

CONSIGLIO SUL CLS: il CLS si misura in session window, non come totale progressivo. Il browser raggruppa i layout shift in sessioni (massimo 5 secondi, con pause di 1 secondo tra gli spostamenti) e il punteggio CLS corrisponde alla sessione peggiore. Una serie concentrata di spostamenti durante il caricamento della pagina può far fallire il CLS anche se il resto della visita è del tutto stabile.

Step 1: controlla il CLS in Search Console

Prima di modificare qualsiasi cosa, accertati di avere davvero un problema di CLS. Accedi a Google Search Console, vai su Core Web Vitals e controlla sia la versione mobile che quella desktop.

Se Google contrassegna gli URL con «Problema CLS: superiore a 0,25» o «Problema CLS: superiore a 0,1», hai la conferma dal Chrome User Experience Report (CrUX) che gli utenti reali riscontrano layout shift sul sito.

A differenza di LCP e INP, dove contano la potenza di calcolo pura e la velocità della rete, i problemi di CLS possono dipendere dallo specifico dispositivo o dalle dimensioni dello schermo. Quando un problema simile colpisce sia mobile che desktop (immagini senza dimensioni, font swap, contenuti iniettati), il desktop può registrare un valore di CLS molto più alto a causa dello schermo più grande (perché viene coinvolta una porzione maggiore della viewport visibile). Search Console raggruppa gli URL per tipologia, quindi indica quali tipi di pagina sono interessati, ma non quali elementi si stanno spostando. Per questo serve il Real User Monitoring.

Google Search Console showing INP issue: longer than 200ms (mobile) with 2.07M affected URLs

Step 2: individua i problemi di CLS con i dati RUM

Search Console conferma l'esistenza del problema, ma non fornisce quasi nulla su cui lavorare. Devi scoprire quali elementi si spostano, su quali pagine e in quali condizioni. Per questo ti serve uno strumento di RUM.

Ho creato CoreDash proprio per rispondere a queste domande. Aggiungi un singolo tag script e lo strumento inizia a raccogliere i dati di attribuzione del CLS da ogni visitatore reale. Il dato fondamentale per il debug del CLS è lo shifting element: il nodo DOM effettivo che si è spostato. Senza questa informazione, fai debug alla cieca.

Individua gli elementi che si spostano

Inizia analizzando i dati del CLS raggruppati per elemento. In CoreDash, vai alla pagina CLS e consulta la tabella ordinata per «CLS by Element». Mostra quali elementi causano il maggior numero di layout shift tra tutti i visitatori. Clicca sull'elemento peggiore per filtrare tutte le metriche relative alle pagine in cui quell'elemento si è spostato.

CoreDash showing CLS scores broken down by shifting element.

Individua le pagine interessate

Dopo aver filtrato in base allo shifting element più impattante, controlla la suddivisione per URL. I problemi di CLS possono riguardare l'intero sito o singoli template. Ora puoi vedere se il CLS si concentra su tipi specifici di pagina: schede prodotto con gallerie di immagini, articoli del blog con spazi pubblicitari o landing page con animazioni hero. Sapere quali pagine falliscono ti indica dove concentrarti.

Confronta nuovi visitatori e visitatori ricorrenti

È un altro controllo rapido che eseguo sempre, e conta più di quanto si pensi. Il CLS da font swap avviene solo quando il font non è in cache. Il CLS delle immagini causato da width: auto si presenta solo quando l'immagine non è nella cache del browser. Se il CLS risulta molto peggiore per chi visita il sito per la prima volta, hai a che fare con uno spostamento legato alla cache. Come developer non lo vedrai mai sulla tua macchina, a meno di non disabilitare la cache (consiglio: disattiva sempre la cache di Chrome... ma questa è un'altra storia).

Controlla tipi di dispositivo e dimensioni della viewport

Di solito il CLS presenta una dinamica mobile/desktop diversa rispetto a LCP e INP. I layout responsive possono introdurre spostamenti che compaiono solo a determinate larghezze e altezze della viewport. Uno spazio pubblicitario problematico su desktop potrebbe non rientrare nemmeno nella viewport mobile. Un menu di navigazione potrebbe animarsi in modo diverso ai breakpoint più piccoli. Raggruppa i dati del CLS per tipo di dispositivo per scoprire dove si verificano.

Step 3: esegui il debug del CLS con Chrome

I dati RUM ti hanno mostrato quali elementi si spostano e perché. Ora riproduci il problema in locale e individua la causa scatenante.

Usa il Core Web Vitals Visualizer

Il modo più rapido per vedere i layout shift è usare l'estensione Chrome Core Web Vitals Visualizer. Carica la pagina, clicca sull'icona dell'estensione e ricarica. Ogni layout shift viene evidenziato con un overlay colorato che mostra con precisione cosa si è mosso e di quanto. Lo uso come primo passaggio prima di aprire il pannello Performance, perché dà una risposta visiva immediata.

Core Web Vitals Visualizer showing layout shifts highlighted on the page.

Riproduci le condizioni in Chrome e controlla gli screenshot di rete

I problemi di CLS sono spesso invisibili a cache calda. Apri DevTools, disabilita la cache nella scheda Network e limita la connessione impostandola su «Slow 4G» (la mia opzione preferita: fa emergere il CLS causato da race condition). Clicca sull'icona dell'ingranaggio e disabilita la cache (con DevTools aperto). In questo modo simuli le condizioni vissute dai visitatori alla prima visita. Vai nella scheda Network e attiva gli screenshot. Ora ricarica la pagina e osserva dove avvengono gli spostamenti.

Chrome DevTools Network tab with screenshots showing request timing for CLS analysis

Usa il pannello Performance di Chrome

Sapendo dove guardare, la maggior parte dei layout shift è facile da individuare, ma a volte qualcuno sfugge. In questi casi apri Chrome DevTools (Ctrl+Shift+I) e passa al pannello Performance per un debug approfondito. Premi Ctrl+Shift+E per ricaricare la pagina e registrare. Dopo il caricamento, scorri verso il basso e verso l'alto un paio di volte. Interrompi la registrazione.

Cerca la traccia «Layout Shifts». Ogni spostamento compare come un blocco colorato. Clicca su uno shift per visualizzare:

  • The shifting node: l'elemento DOM che si è mosso
  • The shift score: impact fraction moltiplicata per distance fraction
  • hadRecentInput: indica se un input dell'utente ha preceduto lo spostamento (click e tap beneficiano di una tolleranza di 500 ms, lo scroll no)

Presta attenzione al momento in cui avvengono gli spostamenti. Gli shift durante il caricamento della pagina rimandano a immagini senza dimensioni, font swap o transizioni CSS. Gli shift durante lo scorrimento indicano animazioni legate allo scroll che usano proprietà di layout.

Chrome Performance panel showing layout shift entries during scrolling.

Test rapido: disabilita tutte le transizioni

Le transizioni CSS che animano proprietà di layout sono una causa subdola di CLS: si attivano solo durante la fase di caricamento e risultano difficili da riprodurre. Incolla questo snippet nella console, ricarica forzatamente la pagina con la cache disattivata e confronta il CLS:

document.head.insertAdjacentHTML('beforeend',
  '<style>*{transition-property:none!important}</style>');

Se dopo aver disabilitato le transizioni il CLS cala, hai individuato la causa. Consulta la guida al debug delle transizioni CSS per individuare le transizioni responsabili.

Misurare il CLS con la Layout Instability API

La Layout Instability API offre accesso diretto a ogni layout shift in JavaScript. È la stessa API usata internamente dagli strumenti di RUM:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      console.log('Layout shift:', {
        value: entry.value,
        sources: entry.sources?.map(s => ({
          node: s.node,
          previousRect: s.previousRect,
          currentRect: s.currentRect
        }))
      });
    }
  }
});
observer.observe({ type: 'layout-shift', buffered: true });

L'array sources mostra quali elementi si sono spostati. hadRecentInput esclude gli spostamenti previsti generati da click e tap. Per le misurazioni in produzione, usa CoreDash o un altro strumento di RUM.

Step 4: risolvi i problemi di CLS

Sai quali elementi si spostano e perché: è ora di sistemarli. Il CLS non ha fasi sequenziali come l'LCP. I layout shift hanno invece categorie di cause ben distinte. Ecco le più comuni, nell'ordine in cui le incontro durante gli audit.

1. Immagini, video e iframe senza dimensioni

È la prima causa di CLS sul web. Il Web Almanac 2025 rileva che il 62% delle pagine mobile contiene almeno un'immagine senza dimensioni. Il fix: includi sempre gli attributi width e height sui tag <img>, <video> e <iframe>.

<img src="hero.jpg" width="800" height="450" alt="Description">

<style>
img {
    height: auto;
    max-width: 100%;
}
</style>

Attenzione a width: auto nel CSS. Questa singola dichiarazione sovrascrive il calcolo dell'aspect ratio del browser e causa layout shift anche quando hai impostato width e height nell'HTML. L'ho visto su decine di siti: chi sviluppa fa tutto a regola d'arte nel markup, ma una regola CSS globale come img { width: auto; height: auto; max-width: 100%; } vanifica tutto. Per la spiegazione completa, vedi come risolvere i layout shift causati dalle immagini con auto-sizing. Per una guida completa che copre tutte le cause di CLS legate a immagini e media (video, iframe, art direction, immagini responsive, lazy loading, placeholder), consulta in che modo immagini e media provocano layout shift.

2. Swap dei web font

Quando un web font viene caricato e sostituisce il font di fallback, la differenza di dimensioni provoca un layout shift. Il Web Almanac 2025 mostra che solo l'11% delle pagine esegue il preload dei web font. Significa che la quasi totalità dei siti è vulnerabile al CLS da font swap.

Il fix si divide in due parti. Prima di tutto, fai combaciare le dimensioni del font di fallback con quelle del web font usando le metric override:

<style>
@font-face {
    font-family: 'My Font Fallback';
    src: local('Arial');
    size-adjust: 105.2%;
    ascent-override: 93%;
    descent-override: 24%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'My Font';
    src: url('/fonts/myfont.woff2') format('woff2');
    font-display: swap;
}

body {
    font-family: 'My Font', 'My Font Fallback', sans-serif;
}
</style>

Usa un Fallback Font Generator per calcolare i valori di override corretti per la combinazione di font scelta. Secondo punto: velocizza la distribuzione. Ospita i font in locale, esegui il preload del file font critico e usa WOFF2 con subsetting. Per una strategia completa, consulta il caricamento responsive dei web font e come garantire la visibilità del testo durante il caricamento dei web font.

3. Animazioni e transizioni CSS

Secondo il Web Almanac 2025, il 40% delle pagine mobile esegue animazioni non composite. Queste animano proprietà come width, height, top, left, margin e padding, che attivano il ricalcolo del layout a ogni frame.

Il caso più comune è transition: all. Quando scrivi transition: all .3s ease, ogni modifica delle proprietà viene animata, comprese quelle di layout. Durante il caricamento della pagina, gli elementi che passano dallo stato non stilizzato a quello stilizzato producono layout shift che si verificano a intermittenza e sono quasi impossibili da riprodurre in modo coerente. È uno schema che vedo in continuazione.

Il fix: sostituisci le proprietà che attivano il layout con proprietà composite.

  • Usa transform: translateY() invece di top/bottom
  • Usa transform: translateX() invece di left/right
  • Usa transform: scale() invece di width/height
  • Usa opacity invece di visibility combinata con variazioni di altezza
  • Non usare mai transition: all. Specifica la proprietà esatta: transition: background-color .2s ease

transform e opacity vengono eseguiti interamente sul compositor thread e non attivano mai il layout. Per l'intera procedura di debug, vedi layout shift causati da transizioni CSS.

4. Annunci, embed e contenuti iniettati dinamicamente

Gli annunci caricano in ritardo e spingono i contenuti verso il basso. I banner per il consenso ai cookie compaiono e spostano la pagina. Le richieste AJAX iniettano nuovi contenuti senza prima riservare spazio. È sempre lo stesso problema: sulla pagina compare qualcosa che il browser non conosceva al momento del render.

Per tutti questi casi il fix consiste nel riservare lo spazio. Per gli ad slot, imposta una min-height corrispondente alle dimensioni previste dell'annuncio:

<style>
.ad-slot {
    min-height: 250px;
    contain: layout style;
}
@media (min-width: 600px) {
    .ad-slot { min-height: 90px; }
}
</style>

La dichiarazione contain: layout style isola il container dell'annuncio dal resto della pagina. Per i cookie banner, usa position: fixed come overlay invece di spingere i contenuti verso il basso. Per i contenuti AJAX, riserva spazio con min-height. Non serve una stima perfetta: una differenza di 50px genera molto meno CLS rispetto a uno spostamento di 400px dovuto all'assenza di spazio riservato.

Per gli embed di terze parti come YouTube, Google Maps e i widget di chat, usa il facade pattern: mostra un placeholder statico e carica il vero embed solo quando l'utente interagisce. Zero CLS, zero risorse sprecate.

5. Layout shift attivati dallo scroll

Questa è la causa di CLS che Lighthouse non intercetta mai. Lighthouse non scorre la pagina, quindi i layout shift attivati dallo scroll sono totalmente invisibili nei lab data. L'unico modo per trovarli è usare i dati RUM o registrare una traccia nel pannello Performance scorrendo la pagina manualmente.

L'esempio più comune è un header a scomparsa durante lo scorrimento che anima la proprietà top. C'è un dettaglio che molti sviluppatori ignorano: lo scroll non è un input di esclusione nelle specifiche della Layout Instability. Click e tap hanno una finestra di tolleranza di 500 ms. Lo scroll no. Ogni layout shift innescato dallo scroll incide sul punteggio CLS.

Il fix: usa transform: translateY() invece di top per qualsiasi animazione attivata dallo scroll. Lo stesso vale per effetti parallasse, barre di navigazione che si riducono e barre di avanzamento legate allo scorrimento. Se si muove durante lo scroll, animalo con transform. Per la guida passo passo con esempi video, vedi in che modo le animazioni legate allo scroll causano CLS.

Checklist rapida dei fix

Causa del CLS Come rilevarla Fix
Immagini/video senza dimensioni Audit "unsized images" di Lighthouse Aggiungi width e height; rimuovi width: auto dal CSS
Swap dei web font RUM: CLS peggiore solo alla prima visita Override delle metriche dei font; preload di WOFF2; self-hosting dei font
Transizioni CSS Snippet per console per elencare tutte le transizioni Sostituisci transition: all con proprietà specifiche; usa transform/opacity
Annunci a caricamento ritardato Attribuzione RUM che mostra gli elementi container degli annunci min-height sugli ad slot; contain: layout style
Banner di consenso ai cookie Picco di CLS alla prima visita; banner nei dati di attribuzione Usa overlay con position: fixed invece di spingere i contenuti
Animazioni allo scroll Traccia Performance durante lo scroll; field CLS > lab CLS Sostituisci top/left/height con transform

Guide correlate

Per una panoramica completa su tutti i Core Web Vitals, visita l'hub dei Core Web Vitals o usa la Checklist definitiva per i Core Web Vitals per eseguire l'audit dell'intero sito.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Arjen Karel

Ti serve un sito più veloce?

Sono Arjen e da 17 anni sistemo siti lenti. Se hai problemi che non riesci a risolvere da solo, mandami il tuo URL e ne parliamo.

Mandami il tuo URL
Arjen Karel
Arjen Karel, Consulente web performance dal 2009

Perché il fix non funziona?

A volte la CDN serve ancora il vecchio HTML, oppure il fix è finito nel template desktop e il mobile ne usa un altro. Mandami il tuo URL e il problema, e ti rispondo con qualche orario. Prima analizzo i tuoi field data, poi dedichiamo un'ora al tuo sito, ed entro un giorno hai le mie note per iscritto. 350 € IVA esclusa.

Mandami il tuo URL

Non hai uno sviluppatore per il fix? Faccio io il lavoro, su una copia del tuo sito.

Trova e risolvi i problemi di Cumulative Layout Shift (CLS) Core Web Vitals Trova e risolvi i problemi di Cumulative Layout Shift (CLS)