⚡ Prestazioni web

Ottimizzare l'LCP: scomporre il tempo nelle sue quattro fasi

Come diagnosticare un LCP lento dividendolo in TTFB, ritardo di caricamento, durata del download e ritardo di rendering, con interventi mirati per ognuna.

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:

  1. servire formati moderni come AVIF o WebP con un fallback;
  2. offrire più larghezze con srcset, così un telefono non scarica la versione per schermi da 27 pollici;
  3. comprimere con una qualità ragionata, verificando a occhio il risultato invece di usare il valore predefinito dello strumento;
  4. 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.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche