Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

⚡ Come caricare i web font senza perdere velocità e accelerare il rendering del testo

⚡ Come caricare i web font senza perdere velocità e accelerare il rendering del testo

Quando un sito impiega 3 secondi a caricarsi e poi passa un altro secondo a ridisegnare tutto il testo, i visitatori se ne vanno. Non dai concorrenti, chiudono semplicemente la scheda. Il problema è quasi sempre lo stesso: web font caricati senza considerare le performance.

Secondo i dati di HTTP Archive per il 2025, circa l'84% dei siti usa web font personalizzati e il sito mediano effettua 5 richieste a file di font per un totale di circa 400 KB. Su una connessione scarsa, questo significa 2-3 secondi di blocco della renderizzazione durante i quali gli utenti vedono una schermata bianca. Google inoltre considera il Cumulative Layout Shift causato dallo scambio dei font nei Core Web Vitals.

I quattro passaggi qui sotto non sono teoria. Sono il minimo pratico che affronta la stragrande maggioranza dei problemi di performance dei web font. Ogni passaggio richiede dai 5 ai 15 minuti.

💡 Panoramica rapida:

  • Decidi i formati: woff2 come primario e woff come fallback sono sufficienti per tutti i browser moderni.
  • Aggiungi il preload per i font critici così il browser inizia subito il download invece di aspettare i CSS.
  • Controlla il tuo font-face: local(), ordine corretto dei src, unicode-range per i caratteri latini.
  • Imposta font-display: swap e i visitatori vedranno il testo all'istante anche mentre il font è ancora in caricamento.

Passaggio 1: Usa woff2 e woff, non serve altro

Esistono molti formati di web font: EOT, TTF, OTF, SVG. Ma nel 2026 te ne servono davvero solo due.

woff2 è lo standard moderno. I file sono più piccoli del 30% rispetto a woff a parità di qualità perché usano la compressione brotli invece di gzip. Il supporto dei browser include tutti i browser evergreen, inclusi Safari mobile e Samsung Internet. A livello globale, oltre il 98% degli utenti.

woff è il fallback per una piccola frazione di browser più vecchi (Safari su iOS 11 e precedenti, rari ambienti aziendali). È anch'esso compresso e funziona ovunque da IE9 in poi. Mettilo per ultimo in src e il browser prenderà woff2 se può, altrimenti ripiegherà su woff.

Non usare EOT (Internet Explorer 8 e precedenti) o TTF (formato raw, senza compressione) nel 2026. La quota di questi browser è rumore statistico e ogni formato extra in src aumenta la dimensione del CSS e confonde il browser.

Se hai file in TTF o OTF, convertili usando un generatore online. Transfonter produce woff2 e woff in un'unica operazione, mostrando un'anteprima dei glifi e la dimensione finale del file. Un'alternativa è Font Squirrel Webfont Generator.

Passaggio 2: Fai il preload dei font critici

Il browser viene a conoscenza dei font dal CSS e legge il CSS dopo l'HTML. Quando ci arriva, su una connessione media sono passati 500-800 ms. Il preload azzera questo ritardo: il browser inizia a scaricare il font non appena incontra il tag nell'<head>, senza aspettare il CSS.

Tag minimo funzionante:

1<link rel="preload" as="font"
2 href="/fonts/open-sans.woff2"
3 type="font/woff2"
4 crossorigin="anonymous">

La chiave è crossorigin="anonymous". Senza, il browser ignora il font in preload e lo scarica di nuovo. Il motivo è che i font sono recuperati in modo anonimo (CORS), ma il preload senza crossorigin effettua una richiesta normale. Il browser li considera risorse diverse e non li abbina.

Cosa mettere in preload. Non tutti i font del sito. Solo quello usato per il testo principale above the fold (above the fold): titoli, corpo, navigazione. Il resto può aspettare. Fare il preload di 4-5 file dà rendimenti decrescenti e sottrae banda ai contenuti critici.

Nota importante su Google Fonts e CDN. Se usi font da Google Fonts, i file vengono aggiornati periodicamente e un link di preload a una vecchia versione causerà un doppio download (vecchia + nuova). Invece del preload per i font da CDN, usa <link rel="preconnect"> verso il dominio del font. Questo accelera l'handshake senza il rischio di disallineamento delle versioni:

1<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

Prefetch per i font secondari. rel="prefetch" dice al browser: "questa risorsa servirà dopo, caricala quando il contenuto principale è pronto". Adatto per i font su pagine interne o le icone font nel footer. La priorità è bassa, non sottrae banda.

Una guida moderna alla prioritizzazione delle risorse è disponibile nella documentazione di web.dev.

Passaggio 3: Scrivi @font-face correttamente

A prima vista, @font-face sembra semplice. In pratica, ha quattro aree delicate, ognuna delle quali influisce sulla velocità.

Esempio di dichiarazione corretta:

1@font-face {
2 font-family: 'Open Sans';
3 font-weight: 400;
4 font-style: normal;
5 font-display: swap;
6 unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC,
7 U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074,
8 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
9 U+FEFF, U+FFFD;
10 src: local('Open Sans'),
11 url('/fonts/open-sans.woff2') format('woff2'),
12 url('/fonts/open-sans.woff') format('woff');
13}

Analisi per punti:

local(): primo in src. Se l'utente ha già il font installato sul suo sistema (Roboto su Android, Segoe UI su Windows, San Francisco su macOS), il browser prende la copia locale e scarica zero byte. Metti sempre local() come prima riga in src. Prendi il nome dal file del font stesso: local('Open Sans') e local('Roboto Regular').

Ordine dei formati. Il browser scorre src da sinistra a destra e prende il primo formato che capisce. Quindi: local()woff2woff. Niente EOT/TTF/SVG alla fine, a meno che tu non abbia un pubblico specifico con browser vecchi, e in quel caso vanno DOPO woff (non prima).

unicode-range: carica solo i glifi che ti servono. Per i caratteri latini, l'intervallo U+0000-00FF (Basic Latin + Latin-1 Supplement) è sufficiente. Sono circa 250 glifi contro diverse migliaia del set completo. La dimensione effettiva del file si riduce di 3-5 volte. Non sovraccaricare l'intervallo: ogni blocco unicode extra aggiunge glifi che nessuno vedrà. Per i siti in cirillico, aggiungi U+0400-04FF.

Ordine dei blocchi @font-face. Se hai più pesi (regular, bold, italic), metti il peso regular (font-weight: 400) per primo. Il browser inizierà a scaricare quello.

Passaggio 4: Attiva font-display: swap e di' addio al FOIT

Il Flash of Invisible Text (FOIT) si verifica quando il browser nasconde il testo per 3 secondi in attesa del font. Gli utenti vedono una pagina bianca. Il Flash of Unstyled Text (FOUT) si verifica quando il testo è immediatamente visibile in un font di sistema, per poi essere sostituito con quello personalizzato. La seconda opzione è sempre migliore della prima.

font-display: swap in @font-face fa esattamente questo: il testo viene renderizzato all'istante in un font di sistema e, quando il font personalizzato si carica, viene scambiato. Ideale per il testo corpo.

Altri valori e quando usarli:

  • swap: per il testo corpo. Il testo è visibile immediatamente, la sostituzione è fluida.
  • optional: per font decorativi e icone. Il browser decide se scaricare o meno il font. Su una connessione scarsa, rifiuterà e manterrà il font di sistema. Il periodo di attesa è di 100 ms.
  • block: blocco breve (di solito 3 secondi), poi il testo è visibile, il font verrà scambiato quando caricato. Raramente usato.
  • fallback: un compromesso. Blocco breve, poi il testo è visibile, il font verrà scambiato se si carica rapidamente.

In pratica, usa swap per il testo corpo e optional per le icone font e la decorazione. Questo è sufficiente.

Comportamento del browser senza font-display. Se non specifichi nulla, Chrome nasconde il testo fino a 3 secondi, Firefox fino a 3 secondi, Safari a tempo indeterminato ed Edge mostra subito il font di sistema. Con font-display: swap, questo comportamento viene unificato e il risultato è prevedibile.

Come verificare il risultato

Testa il tuo sito prima e dopo su web.dev/measure. Lighthouse mostrerà "Assicurati che il testo rimanga visibile durante il caricamento dei webfont" come voce separata. Se l'audit è rosso, il tuo font-display non funziona o è assente.

Per la verifica manuale: apri DevTools → Network, imposta il throttling su "Slow 3G" e aggiorna la pagina. Il testo dovrebbe apparire subito in un font di sistema, non dopo 3 secondi di schermata bianca.

Gli screenshot qui sotto mostrano la differenza tra l'approccio standard e quello ottimizzato (test su Slow 3G):

Caricamento standard dei font con blocco del testo

Default: il testo è nascosto finché il font non si carica

Caricamento ottimizzato con visualizzazione immediata del testo

Comportamento ottimizzato: il testo è visibile immediatamente in un font di sistema

La differenza è visibile a occhio nudo: il primo screenshot mostra una schermata bianca, il secondo mostra il contenuto disponibile all'istante.

Alla conferenza performance.now() 2024, Mandy Michael illustra strategie avanzate: unicode-range incrementale, slicing dei font e lavoro con i font variabili. Per chi vuole andare oltre i quattro passaggi di base.

⁉️🤔 Domande frequenti

Perché mi serve woff se woff2 è supportato ovunque?

I restanti utenti di vecchie versioni di iOS Safari (iOS 11 e precedenti) e rari ambienti aziendali con browser bloccati non supportano woff2. Senza un fallback woff, questi utenti vedranno un font di sistema invece del tuo. Woff aggiunge 15-20 KB al set: un prezzo irrisorio per coprire la quota rimanente.

Posso semplicemente usare Google Fonts e non preoccuparmi?

Sì, e per la maggior parte dei siti questa è la strada ottimale. Google Fonts serve automaticamente woff2 ai browser moderni, usa una CDN geodistribuita e supporta display=swap come parametro URL. Svantaggi: dipendenza da una CDN esterna (considerazioni sulla privacy, GDPR), impossibilità di controllare unicode-range e l'installazione locale dei font. Se privacy e controllo sono importanti, ospita i font in proprio.

Come faccio a sapere se i font stanno davvero rallentando il mio sito?

Lighthouse (la scheda Audits in Chrome DevTools) mostrerà l'audit "Assicurati che il testo rimanga visibile durante il caricamento dei webfont". WebPageTest fornisce una cascata con i tempi per ogni richiesta di font. Se i font partono dopo il primo CSS, il preload non è configurato. Se lo spostamento del layout è superiore a 0,1, il font sta causando Cumulative Layout Shift e Google lo conteggia nei Core Web Vitals.

font-display: swap rovina il design, il testo "salta" allo scambio?

Sì, questo è un noto svantaggio di swap. Combattilo con due tecniche. Prima: imposta font-size e line-height per il testo in modo che corrispondano al font di sistema di fallback. La differenza nelle metriche sarà minima. Seconda: usa Font Style Matcher o la proprietà size-adjust in @font-face (disponibile nei browser moderni) per far corrispondere le metriche del font personalizzato a quelle del font di sistema. Dopo la regolazione, il CLS sarà zero.

Dovrei fare il preload di tutti i font del sito?

No. Fai il preload solo dei font critici: quelli che compongono il testo above the fold (le prime 1-2 schermate). Carica il resto normalmente tramite CSS. Fare il preload di oltre 5 font intasa la banda e ritarda risorse più importanti in coda. In pratica, 1-2 link di preload coprono la stragrande maggioranza degli scenari.

Ne vale la pena: quattro passaggi, quattro minuti

Configurare i web font non è un progetto di una settimana. Convertire in woff2, sistemare @font-face, il preload e font-display: swap richiede 20-30 minuti di lavoro, anche se non l'hai mai fatto prima.

Il beneficio è misurabile: il testo diventa visibile 1,5-2,5 secondi prima su Slow 3G. I Core Web Vitals non penalizzano per lo spostamento del layout. E gli utenti non se ne vanno mentre fissano una schermata bianca.

Inizia con un font: il font principale del testo corpo. Esegui i quattro passaggi. Controlla Lighthouse prima e dopo. La differenza nei numeri sarà più convincente di qualsiasi argomento.