CLS su WordPress: Le 7 Cause e i Fix Definitivi
Cumulative Layout Shift misura quanto il contenuto si sposta durante il caricamento. Quando clicchi un link e il pulsante si muove proprio in quel momento? Quello è CLS. Google lo misura e lo usa per il ranking.
La soglia: 0.1 o meno è “buono”. Sopra 0.25 è “scarso”. WordPress ha diversi colpevoli ricorrenti.
Causa 1: Immagini Senza Dimensioni
WordPress 5.5+ aggiunge width e height automaticamente. Ma se il tuo tema usa wp_get_attachment_image() con parametri custom o stampa il tag <img> manualmente, le dimensioni possono mancare.
<!-- Causa CLS -->
<img src="photo.jpg" alt="...">
<!-- Fix -->
<img src="photo.jpg" width="800" height="600" alt="...">
Il browser riserva lo spazio prima del download. Nessuno spostamento.
Causa 2: Font Web (FOUT/FOIT)
Il browser carica il fallback font, poi swappa al Google Font quando arriva. Lo swap causa un layout shift visibile.
/* Fix: usa font-display optional per font non critici */
@font-face {
font-family: 'Inter';
src: url('inter.woff2') format('woff2');
font-display: optional; /* Non swappa se il font è lento */
}
Alternativa migliore: self-host i Google Fonts per caricarli più velocemente.
Causa 3: Embed Senza Dimensioni
YouTube, Twitter, iframe di terze parti caricano dopo il contenuto e spostano tutto.
.embed-container { aspect-ratio: 16/9; width: 100%; background: #f0f0f0; }
Causa 4: Cookie Banner dall’Alto
Un cookie banner che appare dall’alto spinge tutto il contenuto in basso. Fix: position: fixed; bottom: 0;
Causa 5: Ads Dinamici
Banner pubblicitari che si caricano dopo il contenuto. Fix: riserva lo spazio con dimensioni fisse nel CSS.
Causa 6: Contenuto Iniettato da JavaScript
Plugin che iniettano barre di notifica, popup, widget dopo il DOM load. Ogni inserimento sposta il contenuto sottostante.
Causa 7: Web Font Diversi tra Server e Client
Se il server renderizza con un font e il client con un altro (SSR mismatch), il ricalcolo del layout causa CLS. Raro su WordPress classico, comune su WordPress headless con Next.js.
Come Misurare il CLS
// Console Chrome DevTools
new PerformanceObserver((list) => {
let cls = 0;
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) cls += entry.value;
}
console.log('CLS:', cls);
}).observe({type: 'layout-shift', buffered: true});
FAQ
CLS 0.00 è realistico?
Sì, per pagine semplici (blog post con testo e immagini dimensionate). Per pagine con embed, ads, e widget dinamici, 0.05-0.08 è un buon target realistico.
Il lazy loading causa CLS?
No, se le immagini hanno width e height. Il browser riserva lo spazio anche per le immagini lazy. Il CLS da lazy loading è un mito.