Il Largest Contentful Paint misura quando compare sullo schermo l'elemento più grande visibile all'apertura della pagina: di solito un'immagine di copertina, un video con poster o un blocco di testo. La soglia considerata buona è 2,5 secondi al 75° percentile delle visite reali. Sapere che il proprio LCP è di 4 secondi, però, non dice nulla su dove si perdono quei secondi. Il metodo più utile che conosco è scomporlo in quattro fasi consecutive e attaccare quella più lunga.
Le quattro fasi dell'LCP
Ogni LCP è la somma di quattro intervalli:
| Fase | Da… | A… |
|---|---|---|
| TTFB | inizio della navigazione | primo byte dell'HTML |
| Ritardo di caricamento | primo byte | inizio del download della risorsa LCP |
| Durata del caricamento | inizio download | fine download della risorsa LCP |
| Ritardo di rendering | fine download | elemento disegnato a schermo |
Se l'elemento LCP è un testo, le due fasi centrali valgono zero e resta solo la distanza tra TTFB e rendering, che dipende quasi sempre da CSS e font bloccanti.
Come riferimento orientativo, in una pagina sana il TTFB e la durata del download occupano la parte principale del tempo, mentre i due "ritardi" dovrebbero essere piccoli. Quando i ritardi dominano, significa che il browser ha perso tempo senza fare nulla di utile per l'elemento più importante.
Come misurare le fasi
Nel pannello Performance di Chrome DevTools, registrando un caricamento, la traccia LCP mostra la scomposizione in sottoparti. In alternativa la libreria JavaScript web-vitals, nella build di attribuzione, restituisce per ogni misura i quattro valori e l'elemento coinvolto: è il modo migliore per ottenere la scomposizione anche dai visitatori reali, raccogliendola insieme alla metrica.
Prima di tutto bisogna identificare quale elemento è l'LCP. Spesso non è quello che ci si aspetta: su mobile può essere un paragrafo introduttivo, su desktop la foto principale. Si ottimizza l'elemento giusto, non quello che sembra importante a noi.
Fase 1: TTFB lento
Se il primo byte arriva dopo un secondo o più, tutto il resto parte in ritardo. Le cause tipiche sono pagine generate a ogni richiesta senza cache, query lente al database, redirect a catena (http verso https, poi verso www, poi verso la lingua) e server lontani dagli utenti. Gli interventi: cache della pagina HTML, eliminazione dei redirect superflui, un punto di distribuzione più vicino al pubblico.
Fase 2: ritardo di caricamento
È la fase più sottovalutata. Il browser ha già l'HTML, ma non ha ancora cominciato a scaricare l'immagine principale. Succede quando:
- l'immagine è impostata come sfondo in un file CSS, quindi viene scoperta solo dopo il download e l'analisi del foglio di stile;
- l'immagine viene inserita da JavaScript, per esempio da uno slider o da un framework che renderizza lato client;
- l'immagine ha
loading="lazy", che ne rimanda il caricamento finché il layout non conferma che è nel viewport; - molte altre risorse competono e l'immagine riceve una priorità bassa.
Le correzioni sono dirette. L'immagine LCP deve essere presente nell'HTML iniziale come normale tag img, senza lazy loading, e conviene segnalarla con fetchpriority="high". Se proprio deve restare uno sfondo CSS, un link rel="preload" nell'intestazione permette al browser di scoprirla subito.
<img src="/img/copertina-1200.avif" width="1200" height="675"
fetchpriority="high" alt="Sala riunioni con vista sul porto">
Fase 3: durata del caricamento
Qui conta il peso del file e la velocità con cui arriva. Una foto di copertina da 900 KB su una connessione mobile media richiede tempo, a prescindere da qualsiasi priorità. Gli interventi:
- servire formati moderni come AVIF o WebP con un fallback;
- offrire più larghezze con
srcset, così un telefono non scarica la versione per schermi da 27 pollici; - comprimere con una qualità ragionata, verificando a occhio il risultato invece di usare il valore predefinito dello strumento;
- servire l'immagine dallo stesso dominio della pagina o da uno già connesso, per evitare una nuova negoziazione TLS.
Fase 4: ritardo di rendering
L'immagine è scaricata ma non viene ancora mostrata. Le ragioni più frequenti sono fogli di stile ancora in download, script sincroni nell'intestazione che bloccano il parser, un font web che nasconde il testo LCP finché non arriva, oppure un'animazione di ingresso che parte con opacità zero. Quest'ultimo caso è comune nei temi grafici: l'elemento è pronto, ma un effetto di dissolvenza lo rende visibile solo mezzo secondo dopo.
Si risolve riducendo il CSS bloccante a quello davvero necessario, spostando gli script con defer e togliendo le animazioni di ingresso dall'elemento principale.
Un esempio concreto
Su un sito di un piccolo studio professionale, il caso tipico è questo: LCP di 4,1 secondi su mobile. La scomposizione mostra TTFB di 0,6 secondi, ritardo di caricamento di 2,2 secondi, download di 0,9 secondi e rendering di 0,4. Il problema non è il peso dell'immagine ma il fatto che sia lo sfondo di uno slider caricato via JavaScript. Trasformata la prima slide in un tag img statico con priorità alta, il ritardo di caricamento scende sotto i 200 millisecondi e l'LCP complessivo rientra sotto la soglia senza toccare il server.
In sintesi
- L'LCP è la somma di TTFB, ritardo di caricamento, durata del download e ritardo di rendering.
- Misura la scomposizione e intervieni sulla fase più lunga, non a caso.
- L'immagine LCP va nell'HTML iniziale, senza lazy loading e con
fetchpriority="high". - Peso del file e formati moderni incidono sulla durata del download.
- CSS, script bloccanti e animazioni di ingresso allungano l'ultimo tratto.