Google nel 2020 ha deciso che l'esperienza di pagina conta per il ranking, e ci ha dato tre numeri per riassumerla. Quei tre numeri sono i Core Web Vitals. I nomi fanno paura (LCP, INP, CLS) ma ognuno misura qualcosa che a una persona normale interessa: la pagina si è caricata abbastanza in fretta, reagisce quando clicco, non balla mentre leggo.

Questo articolo spiega cosa misura davvero ognuno, cosa tende a romperlo, come si sistema. Senza buzzword.

LCP: Largest Contentful Paint

Cosa misura: quanti secondi sono passati prima che il più grande elemento visibile a schermo finisse di caricarsi. Quell'elemento di solito è un'immagine hero, un grande titolo, o il poster di un video.

La soglia: sotto 2,5 secondi è "good", da 2,5 a 4 è "needs improvement", oltre 4 è "poor".

Cosa tende a romperlo:

  • Un'immagine hero più grande del necessario (un JPEG da 4 MB quando un AVIF da 200 KB basterebbe).
  • Un'immagine hero caricata in lazy-loading. Il lazy-loading è per le immagini sotto la piega; se metti in lazy l'hero, il browser aspetta prima di scaricarla e l'LCP schizza.
  • Un'immagine hero caricata da una CDN di terze parti lenta.
  • La pagina lenta a iniziare il rendering proprio (server lento, CSS o JavaScript render-blocking nell'head).
  • Un web font che il browser aspetta prima di disegnare il testo che si rivela essere l'elemento LCP.

Come si sistema:

  • Comprimi bene l'immagine LCP. AVIF o WebP a qualità 70-80 sono di solito 1/5 del peso di un JPEG non ottimizzato.
  • Aggiungi fetchpriority="high" al tag dell'immagine hero. Dice al browser "scarica questa prima di tutto il resto".
  • Assicurati che l'immagine LCP non sia un background CSS. Le background CSS vengono scoperte tardi dal browser. Usa un vero tag <img>.
  • Fai preload dei web font con rel="preload" se l'elemento LCP è un titolo.
  • Servi da CDN se il tuo origin è lontano dal tuo pubblico.

L'LCP è il più semplice dei tre da sistemare. L'80% del guadagno viene dall'immagine fatta giusta.

INP: Interaction to Next Paint (ha sostituito FID nel 2024)

Cosa misura: quando un utente clicca, tocca o digita, quanti millisecondi passano prima che la pagina risponda visibilmente. È misurato sull'intera sessione, e l'evento peggiore (o quasi) viene riportato. Sostituisce il vecchio First Input Delay, che misurava solo la prima interazione.

La soglia: sotto 200 ms è "good", 200-500 è "needs improvement", oltre 500 è "poor".

Cosa tende a romperlo:

  • JavaScript pesante che gira sul main thread e blocca gli event handler dal partire.
  • Script di terze parti (analytics, ads, chat, A/B testing) che si mangiano la CPU quando l'utente clicca.
  • Event handler che fanno troppo lavoro sincrono (parsano 50 KB di JSON, fanno una manipolazione DOM che innesca un layout, ordinano un array grosso).
  • Componenti React/Vue che ri-renderizzano gran parte della pagina su una piccola interazione.

Come si sistema:

  • Sposta il lavoro pesante fuori dal main thread (Web Worker, requestIdleCallback).
  • Defer o async sugli script di terze parti che non sono critici per la prima interazione.
  • Spezza i task lunghi in pezzi più piccoli. I browser misurano come "long task" tutto sopra i 50 ms; punta a tenere ogni pezzo di lavoro sotto quella soglia.
  • Usa <button> e <a> come si deve, così il browser gestisce gratis il feedback visivo; non reimplementare aree cliccabili con <div onclick> e 200 righe di JS.

L'INP è la metrica che punisce i WordPress carichi di plugin. Un sito con 20 plugin attivi, metà dei quali iniettano JS su ogni pagina, qui fatica. Audit, disattiva, sostituisci.

CLS: Cumulative Layout Shift

Cosa misura: quanto il contenuto della pagina si sposta dopo il rendering iniziale. Più precisamente: la somma di tutti gli spostamenti di layout inattesi durante la vita della pagina, pesati su quanto contenuto si è mosso e di quanto.

La soglia: sotto 0,1 è "good", 0,1-0,25 è "needs improvement", oltre 0,25 è "poor". I valori non hanno unità di misura, sono frazioni di viewport-per-distanza.

Cosa tende a romperlo:

  • Immagini senza attributi width e height espliciti. Il browser non sa quanto spazio riservare, fa il layout senza l'immagine, poi sposta tutto quando l'immagine arriva.
  • Web font caricati con font-display: swap e un fallback con metriche molto diverse da quelle del web font. La pagina rendera nel fallback, poi rerendera quando arriva il web font, e tutto si sposta.
  • Pubblicità che si caricano in ritardo e si iniettano nella pagina, spingendo giù il contenuto.
  • Un "cookie banner" o "newsletter modal" che appare 2 secondi dopo il caricamento e spinge giù il contenuto.
  • Componenti che si caricano in ritardo e ridimensionano la pagina (carosello, embed, widget dinamici).

Come si sistema:

  • Imposta sempre width e height su <img>, <video>, <iframe>. I browser moderni li usano per calcolare l'aspect ratio e riservare lo spazio.
  • Usa aspect-ratio in CSS per i container di cui conosci il rapporto.
  • Per i web font, usa i nuovi descriptor CSS size-adjust e ascent-override per far combaciare il fallback con il font vero, così lo swap diventa invisibile.
  • Riserva spazio per le pubblicità con un container ad altezza fissa, anche se l'annuncio non è ancora arrivato.
  • Mostra banner e modali come overlay che non spingono il contenuto, non come blocchi iniettati.

Il CLS è il più facile da peggiorare per sbaglio. Aggiungere un widget di terze parti basta.

Da dove arrivano i dati

Le fonti sono due, e dicono cose diverse.

Lab data: un test sintetico fatto da strumenti come Lighthouse, PageSpeed Insights, WebPageTest. Simulano un utente con un device e una rete specifici, eseguono la pagina, misurano. Utili in sviluppo perché sono ripetibili.

Field data (RUM): real user monitoring. Google raccoglie metriche anonime dai veri utenti Chrome che visitano il tuo sito (il Chrome User Experience Report, CrUX). Il dato è il percentile (di default il 75esimo) su 28 giorni. È quello che Google usa come segnale di ranking. PageSpeed Insights mostra lab e field affiancati.

La trappola: il dato di lab è veloce perché il test gira da una stanza pulita con condizioni controllate. Il dato di field è di utenti reali con telefoni vecchi, reti lente, estensioni del browser, robaccia in cache. Il field è quello che conta per la SEO. Il lab è utile ma non è autorevole.

Se il tuo Lighthouse di lab fa 95 e l'LCP di field è 5 secondi, non fidarti del 95. Gli utenti reali sono lenti, e Google ranka su quello che vedono loro.

Un breve ordine di operazioni

Se vuoi sistemare i Core Web Vitals su un sito che oggi li fallisce:

  1. Prendi il dato di field da PageSpeed Insights o Search Console. Devi sapere cosa vedono gli utenti veri, non il tuo laptop.
  2. Identifica quale fra LCP/INP/CLS sta fallendo. Hanno fix diversi; non sprecare tempo a ottimizzare uno che è già verde.
  3. Sistema prima la fonte di dolore più grande. Per l'LCP, l'immagine hero. Per l'INP, lo script di terze parti più pesante. Per il CLS, le dimensioni mancanti delle immagini.
  4. Ri-misura. Aspetta qualche giorno che il field data si aggiorni.
  5. Itera.

Gli altri 200 consigli che trovi online sono utili ma secondari. Sistema bene i tre qui sopra e quasi tutti i siti passano da "poor" a "good" senza altri interventi.