# Fonts: preload, swap and CLS, measured

Without font-display LCP is 644 ms; with swap it drops to 280 ms and CLS stays at 0.0028. Preload made FCP worse, from 280 to 456 ms.

> Page: https://ui.eneawork.it/blog/performance-font-misurati
> Markdown: https://ui.eneawork.it/blog/performance-font-misurati.md

*2026-11-01*

Senza font-display il testo con font web è rimasto invisibile fino a un LCP di 644 ms; con swap l'LCP è 280 ms con lo stesso CLS di 0,0028. Il preload, nella nostra prova, ha peggiorato il FCP da 280 a 456 ms perché il font ha rubato banda al CSS.

Quattro pagine identiche, ognuna con il font Inter latin regular 48.256 byte scaricato dal sito, caricate cinque volte ciascuna in Chrome 155 headless con puppeteer, rete Slow 4G simulata (1,6 Mbps, 150 ms di RTT) e CPU a 4x. Nessun font-display: FCP 280 ms, LCP 644 ms, CLS 0,0028. swap: FCP 280 ms, LCP 280 ms, CLS 0,0028. swap più preload: FCP 456 ms, CLS 0,0028. optional: FCP 284 ms, CLS 0. Comando: node scripts/perf-lab.js http://localhost:3200/font-swap.html 5. Catalogo: 111.985 componenti, 1.556 blocchi, 12.808 icone da 1.472 librerie, letti da /api/stats il 1 novembre 2026. Soglie: web.dev, CC BY 4.0.

## Le quattro varianti

I 364 ms tra 644 e 280 sono il periodo di blocco: il browser nasconde il testo finché il file non arriva, e l'LCP aspetta quel testo. Con swap il testo appare subito nel font di fallback e il CLS misurato resta identico.

## Il codice

@font-face { font-family: "Inter"; src: url("/fonts/inter-400-latin.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } html { font-family: "Inter", system-ui, sans-serif; }

Il file va servito dalla tua origine, con cache lunga e immutable: quello del sito risponde con max-age=31536000 e pesa 48.256 byte. Il preload del peso usato nel primo schermo ha bisogno di crossorigin, altrimenti il browser scarica il file due volte.

## Perché il preload ha peggiorato l'FCP

Il preload ha anticipato il download del font ma ha anche messo in coda il CSS: su una rete da 1,6 Mbps due file da 48 KB competono, e il primo paint è passato da 280 a 456 ms. Il preload conviene quando il font è davvero nel primo schermo e il CSS è già piccolo; non è una regola universale.

## Le regole che tengono

## Il limite da dichiarare

Il CLS di 0,0028 è piccolo perché il fallback Times e Inter hanno metriche vicine su questo testo. Con un fallback più largo il salto cresce, e un titolo grande sposta molto più di un paragrafo. La prova usa un font e una pagina: la scelta tra swap e optional dipende da quanto conta il carattere tipografico, non solo dal numero.

## Dove continuare

Il catalogo EneUI indicizza 111.985 componenti, per esempio gooey-text-morphing, e la griglia di 12.808 icone come icon-abc. Leggi font-display e CLS, la strategia di preload, le cause del CLS e come si fissa un performance budget.

## FAQ

### font-display: swap è sempre la scelta giusta?

È la scelta predefinita per la maggior parte dei siti: il testo appare subito e il font arriva dopo. Sui loghi e sui titoli di brand si valuta optional.

### Perché il preload può peggiorare le cose?

Perché compete con le risorse che bloccano il rendering. Nella prova il FCP è passato da 280 a 456 ms con il preload attivo.

### Come si riduce il CLS del font?

Con un fallback locale le cui metriche assomigliano al font web, regolate con size-adjust, ascent-override e descent-override. Non basta un line-height fisso.

### Quanti pesi di font servono?

Due nella maggior parte dei casi, regular e bold. Ogni peso è un file da 40-50 KB e su mobile è banda che non torna.

### Meglio self-host o Google Fonts?

Self-host toglie un host terzo, un handshake e un problema di privacy. In cambio devi aggiornare i file quando cambi font.
