⌨️ Sviluppo web

Web font senza rallentare il sito: WOFF2, font-display e subset

Come caricare i web font in modo efficiente: WOFF2, font-display, preload, subset con unicode-range, font variabili e riserve calibrate contro il CLS.

La tipografia è una parte essenziale dell'identità di un sito, e i web font permettono di usare caratteri diversi da quelli installati sul dispositivo. Hanno però un costo: sono file da scaricare, spesso scoperti tardi dal browser, e finché non arrivano il testo può restare invisibile o cambiare aspetto all'improvviso. Con qualche accorgimento puoi avere caratteri curati senza penalizzare velocità e stabilità della pagina.

Il problema: testo invisibile o testo che salta

Quando una regola CSS richiede un font non ancora scaricato, il browser ha due possibilità:

  • FOIT (Flash of Invisible Text): nasconde il testo finché il font non arriva. Su una connessione lenta, l'utente vede una pagina con spazi vuoti al posto dei titoli.
  • FOUT (Flash of Unstyled Text): mostra subito il testo con un font di riserva e lo sostituisce quando il web font è pronto. Il contenuto è leggibile da subito, ma la sostituzione può far cambiare le dimensioni del testo e spostare il layout.

In generale il secondo comportamento è preferibile: leggere subito conta più dell'estetica dei primi istanti. Lo si controlla con font-display.

font-display

La proprietà si dichiara nella regola @font-face:

@font-face {
  font-family: "Testo";
  src: url("/fonts/testo-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

I valori principali:

Valore Comportamento
swap mostra subito il font di riserva e lo sostituisce quando il web font arriva
optional attesa brevissima; se il font non è pronto, usa quello di riserva per tutta la visita
fallback breve attesa, poi riserva; sostituisce solo se il font arriva entro poco tempo
block nasconde il testo per un periodo più lungo prima di usare la riserva

swap è la scelta più comune per i testi. optional è interessante quando la stabilità visiva conta molto: alla prima visita l'utente potrebbe vedere il font di sistema, ma il web font viene messo in cache e usato nelle visite successive, senza alcuno spostamento.

Un solo formato: WOFF2

Oggi non serve più elencare cinque formati diversi in src. WOFF2 offre la compressione migliore ed è supportato da tutti i browser attuali. Se ricevi un font in formato TTF o OTF, convertilo in WOFF2 prima di pubblicarlo, verificando che la licenza del font consenta l'uso sul web.

Ospitare i font sul proprio dominio

Caricare i font da un servizio esterno è comodo, ma comporta una connessione aggiuntiva verso un altro dominio e, in alcuni casi, l'invio dell'indirizzo IP del visitatore a terzi, con possibili implicazioni per la privacy degli utenti. Ospitare i file WOFF2 insieme al resto del sito:

  • elimina la connessione aggiuntiva;
  • ti dà controllo completo su cache e versioni;
  • semplifica la Content Security Policy;
  • evita di trasferire dati dei visitatori a fornitori esterni.

Con nomi di file contenenti un hash puoi assegnare ai font una cache molto lunga.

Precaricare i font critici

Il browser scopre un font solo dopo aver scaricato il CSS e aver trovato un elemento che lo usa: spesso è tardi. Per il font del testo principale, un preload anticipa il download:

<link rel="preload" href="/fonts/testo-regular.woff2"
      as="font" type="font/woff2" crossorigin>

L'attributo crossorigin è necessario anche per font sullo stesso dominio, altrimenti il file viene scaricato due volte. Precarica solo uno o due file davvero indispensabili: precaricare tutte le varianti (corsivo, grassetto, seminegretto) toglie banda alle risorse più importanti.

Ridurre il peso: subset e unicode-range

Un font completo può contenere migliaia di glifi per alfabeti che il tuo sito non userà mai. Il subsetting crea una versione che contiene solo i caratteri necessari, per esempio l'alfabeto latino con accenti e punteggiatura. Il risparmio può essere notevole.

Con unicode-range puoi dividere il font in più file e lasciare che il browser scarichi solo quelli contenenti i caratteri effettivamente presenti nella pagina:

@font-face {
  font-family: "Testo";
  src: url("/fonts/testo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2018-201F;
  font-display: swap;
}

Assicurati che il subset includa tutti i caratteri che ti servono: lettere accentate, virgolette tipografiche, simbolo dell'euro, trattini lunghi. Un carattere mancante viene mostrato con il font di riserva, creando un effetto incoerente.

Font variabili

Un font variabile contiene in un unico file un'intera gamma di pesi (e talvolta di larghezze o inclinazioni). Se usi tre o quattro pesi dello stesso carattere, un file variabile è spesso più leggero della somma dei file statici e offre anche pesi intermedi:

@font-face {
  font-family: "Testo";
  src: url("/fonts/testo-variabile.woff2") format("woff2");
  font-weight: 300 800;
  font-display: swap;
}
h1 { font-weight: 720; }

Calibrare il font di riserva

Quando il web font sostituisce quello di riserva, la differenza di larghezza e altezza delle lettere sposta il testo e contribuisce al CLS. I descrittori size-adjust, ascent-override, descent-override e line-gap-override permettono di adattare un font di sistema alle metriche del web font:

@font-face {
  font-family: "Testo Riserva";
  src: local("Arial");
  size-adjust: 105%;
  ascent-override: 92%;
}
body {
  font-family: "Testo", "Testo Riserva", sans-serif;
}

Considera i font di sistema

Per interfacce, pannelli di amministrazione e testi lunghi, uno stack di font di sistema (system-ui, -apple-system, "Segoe UI", Roboto, sans-serif) offre caratteri ben leggibili, già presenti sul dispositivo e a costo zero. Puoi riservare il web font ai titoli, dove l'identità visiva conta di più.

In sintesi

  • Usa font-display: swap o optional per non nascondere il testo durante il caricamento.
  • Pubblica solo WOFF2 e, quando possibile, ospita i font sul tuo dominio.
  • Precarica soltanto il font del testo principale, con l'attributo crossorigin.
  • Riduci il peso con subset, unicode-range e font variabili quando usi più pesi.
  • Calibra il font di riserva con size-adjust per limitare gli spostamenti del layout.
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