Performance
font-display e il costo in CLS
font-display decide cosa mostra il browser mentre il webfont scarica: swap costa CLS, block nasconde il testo. I cinque valori e come ridurre lo scarto.
In sintesi
- swap mostra subito il fallback e sposta il layout quando arriva il webfont.
- block tiene il testo invisibile per circa 3 s: CLS basso, lettura peggiore.
- size-adjust e le metriche di override riducono lo scarto fra fallback e webfont.
font-display decide cosa mostra il browser mentre il webfont scarica: swap mostra subito il fallback, optional rinuncia al font nelle reti lente, block nasconde il testo. Nessuno dei cinque valori è gratis in CLS.
I cinque valori, in tabella
| Valore | Blocco del testo | Cosa vede il lettore | Costo |
|---|---|---|---|
| auto | Decide il browser | Dipende dal browser | Imprevedibile |
| block | Circa 3 s | Nessun testo | Testo invisibile, poi swap |
| swap | 0 ms | Il fallback | Scarto di metrica |
| fallback | Circa 100 ms | Il fallback, poi il webfont | Scarto breve, poi stabile |
| optional | Circa 100 ms | Il fallback | Nessuno sulle reti lente |
I millisecondi sono quelli documentati su web.dev: circa 3 s di blocco per block, circa 100 ms per fallback e optional. Il numero che conta è la terza colonna: quando il webfont arriva dopo la finestra, il testo non cambia più.
Perché swap sposta il layout
Il fallback ha metriche diverse: altezza delle maiuscole, larghezza media dei caratteri, interlinea. Quando il webfont prende il posto del fallback la riga può cambiare altezza e ogni blocco sotto si sposta. Su un titolo grande lo spostamento si vede, su un paragrafo da 14 px produce un CLS piccolo ma reale.
Ridurre lo scarto, non solo il tempo
- Nel
@font-facedel fallback dichiarasize-adjust,ascent-overrideedescent-override: il testo occupa la stessa altezza prima e dopo. - Metti in preload il solo woff2 della piega, non tutti e 15:
as="font",type="font/woff2",crossorigin. - Tieni i subset latin e latin-ext: gli altri subset sono byte che nessuno legge.
- Usa
font-display: optionalsui pesi decorativi: se arrivano tardi, la pagina non si muove.
Misurare il foglio
grep -c "@font-face" public/fonts.css
grep -c "font-display" public/fonts.css
du -cb public/fonts/*.woff2 | tail -1
Il primo numero dice quanti blocchi dichiari, il secondo quanti dichiarano font-display: se i due valori differiscono, il browser applica auto a quelli che mancano. Il terzo è il peso su disco di tutti i file, 632.280 byte nel nostro caso.
La limitazione da dichiarare
font-display non elimina lo spostamento: decide quando avviene. Con block il CLS resta basso e il testo invisibile per 3 s, che peggiora la lettura e non la metrica. E l'auto-hosting riduce il rischio solo se i file arrivano dalla stessa origine e con cache lunga.
Dove continuare
Nel catalogo: componenti tipografici, gooey text morphing e testo animato. Le guide: font gratuiti per interfacce e tipografia fluida con clamp; l'articolo gemello su CLS e il confronto misurato librerie React 2026.
Domande frequenti
font-display è obbligatorio?
No. Senza dichiarazione il browser usa auto, che di norma si comporta come block per circa 3 secondi. Dichiararlo rende il comportamento esplicito.
swap o optional: quale scegliere?
swap se la famiglia è parte dell'identità e deve comparire; optional se il testo conta più del carattere e un secondo download vale una visita senza font.
font-display risolve il CLS dei font?
No, cambia quando il testo appare. Lo spostamento resta fra fallback e webfont: si riduce con size-adjust, ascent-override e un fallback di metrica simile.
Il preload serve su tutti i pesi?
No. Il preload toglie una richiesta dalla coda, quindi va sul solo file usato nella piega. Precaricare 15 file occupa la banda che serve a CSS e immagini.
I font self-hosted hanno meno CLS?
Non direttamente. Togliere la richiesta a un dominio terzo elimina DNS e connessione, quindi il font arriva prima e la finestra di swap si chiude prima.