Core Web Vitals: guida pratica a LCP, CLS e INP
I Core Web Vitals sono tre metriche con cui Google quantifica l’esperienza utente sulle pagine web. Sono un fattore di ranking dal 2021, ma dal marzo 2024 c’è stato un cambio importante: FID (First Input Delay) è stato sostituito da INP (Interaction to Next Paint), metrica molto più severa e realistica. Molte guide online sono rimaste indietro e citano ancora FID — se le trovi, sappi che sono datate.
Indice contenuti:
Questo articolo copre le tre metriche attuali, le soglie ufficiali, gli strumenti di misurazione e — punto che di solito manca — le cause tecniche reali che le peggiorano e come intervenire.
Le tre metriche e le soglie
Dati ufficiali Google (web.dev/vitals):
| Metrica | Misura | Buono | Da migliorare | Scarso |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Tempo di rendering dell’elemento visibile più grande | ≤ 2,5 s | 2,5 – 4,0 s | > 4,0 s |
| CLS (Cumulative Layout Shift) | Stabilità visiva (quanto “saltano” gli elementi mentre carica) | ≤ 0,1 | 0,1 – 0,25 | > 0,25 |
| INP (Interaction to Next Paint) | Reattività alle interazioni utente (click, tap, tastiera) | ≤ 200 ms | 200 – 500 ms | > 500 ms |
Una pagina è considerata “Good” da Google se tutte e tre le metriche sono nella fascia verde al 75° percentile del traffico reale degli ultimi 28 giorni. “Tutte e tre” è la parte che viene dimenticata: un LCP di 1.8s non ti salva se l’INP è a 400ms.
Dove si misurano: dati di laboratorio vs dati di campo
Distinzione fondamentale che genera confusione costante:
Dati di laboratorio (lab data): un browser simulato esegue la tua pagina in condizioni controllate. Strumenti: Lighthouse, PageSpeed Insights (sezione “Analysis”), DevTools. Velocissimi, ripetibili, ma non sono quelli che Google usa per il ranking.
Dati di campo (field data, CrUX): metriche raccolte da Chrome reale sugli utenti reali che visitano il tuo sito, anonimizzate e aggregate nel Chrome User Experience Report. Sono quelli che contano. Strumenti:
- PageSpeed Insights (sezione “Discover what your real users are experiencing”)
- Google Search Console → Esperienza → Segnali web essenziali
- CrUX Dashboard su Google BigQuery
- RUM proprietario (Real User Monitoring) tramite la
web-vitalslibrary di Google
Regola operativa: Lighthouse serve a trovare cosa peggiora i Vitals. CrUX ti dice se per gli utenti veri la pagina passa o no. Senza traffico sufficiente (tipicamente ~1000 visite/mese), una URL non ha dati CrUX e Google usa dati di origine (sitewide) come fallback.
LCP: il dettaglio che manca in tutte le guide
LCP misura il tempo dal momento in cui l’utente richiede la pagina fino a quando l’elemento visibile più grande del viewport iniziale è stato renderizzato. Di solito è:
- L’hero image / banner principale (e-commerce, landing)
- Il titolo H1 se non c’è immagine grande (blog, articoli)
- Un video poster
- Raramente: un blocco di testo molto grande
La composizione di LCP (ecco dove intervenire)
Google scompone LCP in 4 sotto-tempi:
LCP = TTFB + Resource Load Delay + Resource Load Duration + Element Render Delay
| Sotto-metrica | Cos’è | Come si migliora |
|---|---|---|
| TTFB (Time to First Byte) | Tempo server lato backend + rete | CDN, caching, hosting migliore, ottimizzare query DB |
| Resource Load Delay | Tempo tra inizio pagina e inizio download risorsa LCP | fetchpriority="high" sull’immagine LCP, preload, eliminare lazy loading sull’hero |
| Resource Load Duration | Tempo effettivo di download | Formato immagine (WebP/AVIF), compressione, dimensioni corrette, CDN |
| Element Render Delay | Tempo tra risorsa scaricata e rendering | Ridurre JS bloccante, eliminare render-blocking CSS |
Il singolo intervento con il miglior rapporto sforzo/risultato per migliorare LCP è quasi sempre fetchpriority="high" sull’immagine hero, introdotto da Chrome nel 2023:
<img
src="/hero.webp"
alt="..."
width="1200"
height="600"
fetchpriority="high"
>
Questo dice al browser di scaricare quell’immagine prima di CSS e JS che normalmente avrebbero priorità, riducendo il Resource Load Delay di centinaia di millisecondi.
Errore frequentissimo: lazy loading dell’immagine LCP. loading="lazy" sull’hero fa esplodere l’LCP di 1-2 secondi. L’hero image non va mai in lazy loading.
CLS: cosa lo rompe davvero
CLS misura la somma degli spostamenti inaspettati del layout durante la vita della pagina (finestra di 5 secondi). Un CLS di 0.25 significa che qualcosa è “saltato” in modo fastidioso durante il caricamento.
Cause in ordine di frequenza reale
- Immagini senza attributi
widtheheight. Quando un’immagine carica, se il browser non conosce le proporzioni, deve “allargare” lo spazio al momento del download — tutto il contenuto sottostante salta. Fix:<img src="..." width="800" height="600" alt="...">Oppure CSS
aspect-ratio: 800/600. Funziona anche con immagini responsive. - Ads, embed, iframe senza dimensioni riservate. Google AdSense, video YouTube, widget social, chat widget. Qualsiasi cosa si carichi in asincrono e occupi spazio non dichiarato. Riserva lo spazio con un contenitore di dimensioni fisse.
- Web fonts che causano FOUT/FOIT. Il browser mostra prima il fallback (system font), poi quando il font custom è pronto sostituisce e tutto si riposiziona. Fix:
font-display: optionalnel @font-face (scarica se fa in tempo, altrimenti usa fallback)size-adjustin CSS per matching delle metriche tra fallback e custom font- Preload dei font critici:
<link rel="preload" as="font" ...>
- Contenuto inserito dinamicamente sopra contenuto esistente. Banner cookie che appare in cima alla pagina dopo 200ms, notifica “iscriviti alla newsletter”, toolbar di traduzione. Tutto quello che appare sopra il fold dopo il primo render causa CLS. Soluzione: se deve apparire, fallo come overlay posizionato (che non sposta il flusso) o riserva lo spazio fin dall’inizio.
- Animazioni non-compositor. Animare
width,height,top,leftcausa reflow dell’intera pagina. Usa solotransformeopacity, che il browser può animare sul compositor thread senza ricalcolare il layout.
INP: la metrica che ha ucciso i siti pesanti di JavaScript
INP misura la latenza dell’interazione più lenta durante la visita: dal momento in cui l’utente clicca/tocca/digita, al momento in cui il prossimo frame viene disegnato dopo che il browser ha processato l’evento.
Perché è più severo di FID: FID misurava solo la prima interazione e solo il delay input (il tempo prima che l’handler iniziasse). INP misura il tempo totale — handler + rendering — di tutte le interazioni della visita, e prende il valore peggiore (con correzione per outlier su visite molto lunghe).
Siti single-page con framework pesanti (React, Vue, Angular) che prima passavano FID con FID < 100ms ora falliscono INP con valori di 400-800ms. È un problema reale.
Cause principali di INP alto
- JavaScript di terze parti pesante. Tag manager che carica 15 script, tracking di analytics multipli, chatbot, personalizzazione A/B, heatmap (Hotjar, Clarity). Ogni task sopra i 50ms sul main thread blocca le interazioni.
- Event handler che fanno troppo lavoro sincrono. Un
onClickche esegue 300ms di calcoli prima di aggiornare il DOM blocca tutto per 300ms. Fix: spezzare il lavoro conscheduler.yield()orequestIdleCallback, o spostare calcoli pesanti in Web Workers. - Re-render massicci del framework. In React, uno state update al livello più alto può causare il re-render di tutto l’albero. Fix: memoization (
useMemo,React.memo), virtualizzazione di liste lunghe, code splitting aggressivo. - DOM enormi. Pagine con 3000+ elementi DOM sono naturalmente lente a reagire. Google consiglia < 1500 nodi, < 32 livelli di annidamento, nessun elemento con > 60 figli.
Come diagnosticare INP
Lighthouse non è sufficiente per INP — è una metrica di field data. Strumenti utili:
- Chrome DevTools > Performance panel > Interactions track: mostra esattamente quali interazioni sono lente e dove si blocca il main thread
- web-vitals library con
onINP()per raccogliere dati reali - PageSpeed Insights → Diagnose performance issues > Longest Interaction
Comando base per test live su Chrome:
import { onINP } from 'web-vitals';
onINP((metric) => {
console.log('INP:', metric.value, 'ms', metric);
});
Strumenti: quale usare quando
| Obiettivo | Strumento | Perché |
|---|---|---|
| Diagnosi singola pagina | Lighthouse in DevTools | Veloce, ripetibile, suggerimenti automatici |
| Capire cosa vedono gli utenti reali | PageSpeed Insights (sezione field) | Dati CrUX ufficiali |
| Monitoraggio sitewide | Search Console > Esperienza | Dashboard Google ufficiale per tutto il sito |
| Profilazione dettagliata | DevTools > Performance panel | Flame chart completo, per debug approfondito |
| Real User Monitoring in produzione | web-vitals library + proprio backend |
Dati continui sul tuo traffico, segmentabili per URL/device/browser |
| Confronto con competitor | CrUX Dashboard (BigQuery) | Dati CrUX aggregati pubblici per qualsiasi dominio |
Gerarchia degli interventi
Per un sito mediamente ottimizzato, l’ordine di priorità a maggior ROI è:
- CDN davanti al sito (se non ce l’hai già). Riduce TTFB → migliora LCP globalmente.
- Compressione e formati immagine moderni (WebP/AVIF) + dimensioni corrette. Impatto forte su LCP.
fetchpriority="high"sull’hero image. Guadagno tipico 200-500ms su LCP.- Dimensioni esplicite su tutte le immagini e iframe. Azzera gran parte del CLS.
- Audit script di terze parti (tag manager, analytics, widget): rimuovi quelli che nessuno usa, carica in
deferquelli non critici. Grande impatto su INP. - Font:
font-display: optionaloswap+ preload dei critici. - Code splitting e lazy loading di route non critiche (per SPA).
Tutto il resto (micro-ottimizzazioni CSS, tree shaking avanzato, service worker) è secondario finché non hai sistemato questi sette punti.
Cosa cambia nel 2026
Google ha annunciato che sta valutando l’aggiunta di nuove metriche ai Core Web Vitals:
- Responsiveness extensions: metriche più granulari sulla reattività percepita
- Scroll performance: quanto è fluido lo scroll
- Smooth animations: qualità delle animazioni in termini di frame drop
Nessuna di queste è ancora ufficialmente un ranking factor al momento della scrittura. Tienile d’occhio tramite il Chrome blog e web.dev.
Takeaway
- I Core Web Vitals contano al 75° percentile del traffico reale, non in condizioni di laboratorio
- INP ha sostituito FID nel marzo 2024: se la tua guida di riferimento parla di FID, è datata
- LCP si migliora quasi sempre con: CDN + immagini ottimizzate +
fetchprioritysull’hero - CLS si risolve nell’80% dei casi dichiarando dimensioni a immagini e iframe
- INP è il vero banco di prova dei siti pesanti di JavaScript: se usi React/Vue/Angular su un sito pubblico, auditalo subito
- Passare i Vitals è un requisito, non un vantaggio competitivo: lo fanno tutti i siti seri, non ti distingue
