Ridurre le dimensioni dei caratteri web

La tipografia è fondamentale per un buon design, un buon branding, una buona leggibilità e un'accessibilità ottimale. I caratteri web consentono tutto quanto sopra e altro ancora: il testo è selezionabile, ricercabile, può essere ingrandito ed è compatibile con i DPI elevati, garantendo un rendering del testo coerente e nitido indipendentemente dalle dimensioni e dalla risoluzione dello schermo. I WebFonts sono fondamentali per un buon design, un'esperienza utente e un buon rendimento.

L'ottimizzazione dei caratteri web è un elemento fondamentale della strategia di rendimento complessivo. Ogni carattere è una risorsa aggiuntiva e alcuni caratteri potrebbero bloccare il rendering del testo, ma il fatto che la pagina utilizzi WebFonts non significa che il rendering debba essere più lento. Al contrario, i caratteri ottimizzati, combinati con una strategia ponderata per il modo in cui vengono caricati e applicati nella pagina, possono contribuire a ridurre le dimensioni totali della pagina e a migliorare i tempi di rendering della pagina.

Anatomia di un carattere web

Un carattere web è una raccolta di glifi e ogni glifo è una forma vettoriale che descrive una lettera o un simbolo. Di conseguenza, le dimensioni di un determinato file del carattere sono determinate da due semplici variabili: la complessità dei percorsi vettoriali di ciascun glifo e il numero di glifi in un determinato carattere. Ad esempio, Open Sans, uno dei WebFonts più popolari, contiene 897 glifi, tra cui caratteri latini, greci e cirillici.

Tabella dei glifi dei caratteri

Quando scegli un carattere, è importante considerare quali set di caratteri sono supportati. Se devi localizzare i contenuti della pagina in più lingue, devi utilizzare un carattere che possa offrire agli utenti un'esperienza e un aspetto coerenti. Ad esempio, la famiglia di caratteri Noto di Google ha lo scopo di supportare tutte le lingue del mondo. Tieni presente, tuttavia, che la dimensione totale di Noto, con tutte le lingue incluse, genera un download ZIP di oltre 1,1 GB.

In questo post scoprirai come ridurre le dimensioni dei file dei caratteri web caricati.

Formati dei caratteri web

Attualmente sul web sono in uso due formati di contenitori di caratteri consigliati:

WOFF e WOFF 2.0 godono di un'ampia compatibilità e sono supportati da tutti i browser moderni.

  • Pubblica la variante WOFF 2.0 per i browser moderni.
  • Se assolutamente necessario, ad esempio se devi ancora supportare Internet Explorer 11, pubblica il WOFF come alternativa.
  • In alternativa, puoi evitare di utilizzare i caratteri web per i browser precedenti e utilizzare i caratteri di sistema. Inoltre, potrebbe avere un rendimento migliore anche su dispositivi meno recenti e con meno risorse.
  • Poiché WOFF e WOFF 2.0 coprono tutte le basi per i browser moderni e legacy ancora in uso, l'utilizzo di EOT e TTF non è più necessario e può comportare tempi di download dei caratteri web più lunghi.

Caratteri web e compressione

Sia WOFF che WOFF 2.0 hanno la compressione integrata. La compressione interna di WOFF 2.0 utilizza Brotli e offre una compressione fino al 30% migliore rispetto a WOFF. Per ulteriori informazioni, consulta il report di valutazione WOFF 2.0.

Infine, vale la pena notare che alcuni formati dei caratteri contengono metadati aggiuntivi, come informazioni su anticipazioni dei caratteri e kerning che potrebbero non essere necessarie su alcune piattaforme, il che consente un'ulteriore ottimizzazione delle dimensioni del file. Ad esempio, Google Fonts gestisce più di 30 varianti ottimizzate per ogni carattere e rileva e fornisce automaticamente la variante ottimale per ogni piattaforma e browser.

Definire una famiglia di caratteri con @font-face

La regola at @font-face CSS consente di definire la posizione di una determinata risorsa di caratteri, le sue caratteristiche di stile e i punti di codice Unicode per i quali deve essere utilizzata. Una combinazione di queste dichiarazioni @font-face può essere utilizzata per creare una "famiglia di caratteri", che il browser utilizzerà per valutare quali risorse dei caratteri devono essere scaricate e applicate alla pagina corrente.

Prendiamo in considerazione un carattere variabile

I caratteri variabili possono ridurre notevolmente le dimensioni dei file dei caratteri nei casi in cui hai bisogno di più varianti di un carattere. Anziché dover caricare gli stili normali e in grassetto, oltre alle relative versioni in corsivo, puoi caricare un unico file contenente tutte le informazioni. Tuttavia, le dimensioni dei file dei caratteri variabili saranno maggiori di quelle di una singola variante, anche se inferiori a quelle della combinazione di molte varianti. Anziché un carattere variabile di grandi dimensioni, potrebbe essere meglio pubblicare prima le varianti di caratteri critiche, con le altre varianti scaricate in un secondo momento.

I caratteri variabili sono ora supportati da tutti i browser moderni. Scopri di più nella Introduzione ai caratteri variabili sul web.

Seleziona il formato giusto

Ogni dichiarazione @font-face fornisce il nome della famiglia di caratteri, che funge da gruppo logico di più dichiarazioni, proprietà dei caratteri come stile, spessore e allungamento e il descrittore src, che specifica un elenco con priorità delle posizioni per la risorsa del carattere.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       /* Only serve WOFF if necessary. Otherwise,
          WOFF 2.0 is fine by itself. */
       url('/fonts/awesome.woff') format('woff');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'),
       url('/fonts/awesome-i.woff') format('woff');
}

Innanzitutto, tieni presente che gli esempi precedenti definiscono una singola famiglia di caratteri fantastici con due stili (normale e corsivo), ciascuno dei quali rimanda a un insieme diverso di risorse di caratteri. A loro volta, ogni descrittore src contiene un elenco di varianti di risorse separate da virgole e con priorità:

  • La direttiva local() ti consente di fare riferimento, caricare e utilizzare i caratteri installati localmente. Se l'utente ha già installato il carattere sul proprio sistema, questo metodo bypassa completamente la rete ed è il più veloce.
  • La direttiva url() consente di caricare caratteri esterni e può contenere un suggerimento format() facoltativo che indica il formato del carattere a cui fa riferimento l'URL fornito.

Quando il browser stabilisce che il carattere è necessario, esegue l'iterazione dell'elenco delle risorse fornite nell'ordine specificato e tenta di caricare la risorsa appropriata. Ad esempio, seguendo l'esempio riportato sopra:

  1. Il browser esegue il layout della pagina e determina quali varianti di carattere sono necessarie per visualizzare il testo specificato nella pagina. I caratteri che non fanno parte del modello di oggetti CSS (CSSOM) della pagina non vengono scaricati dal browser perché non sono obbligatori.
  2. Per ogni carattere richiesto, il browser controlla se è disponibile localmente.
  3. Se il carattere non è disponibile localmente, il browser esegue l'iterazione sulle definizioni esterne:
    • Se è presente un suggerimento per il formato, il browser controlla se lo supporta prima di avviare il download. Se il browser non supporta il suggerimento, passa al successivo.
    • Se non è presente alcun suggerimento per il formato, il browser scarica la risorsa.

La combinazione di direttive locali ed esterne con suggerimenti di formato appropriati ti consente di specificare tutti i formati di carattere disponibili e lasciare che il browser gestisca il resto. Il browser determina quali risorse sono necessarie e seleziona il formato ottimale.

Sottoinsieme di intervalli Unicode

Oltre alle proprietà dei caratteri come stile, spessore e allungamento, la regola @font-face consente di definire un insieme di punti di codice Unicode supportati da ogni risorsa. In questo modo puoi suddividere un carattere Unicode di grandi dimensioni in sottoinsiemi più piccoli (ad esempio sottoinsiemi latini, cirillici e greci) e scaricare solo i glifi necessari per visualizzare il testo in una determinata pagina.

Il descrittore unicode-range consente di specificare un elenco di valori di intervallo separati da virgole, ciascuno dei quali può essere in una di tre diverse forme:

  • Un singolo punto di codice (ad es. U+416)
  • Intervallo (ad es. U+400-4ff): indica i punti di codice di inizio e di fine di un intervallo
  • Intervallo di caratteri jolly (ad es. U+4??): i caratteri ? indicano qualsiasi cifra esadecimale

Ad esempio, puoi suddividere la famiglia di caratteri Awesome Font in sottoinsiemi di caratteri latini e giapponesi, ognuno dei quali viene scaricato dal browser in base alle necessità:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-jp.woff2') format('woff2');
  /* Japanese glyphs */
  unicode-range: U+3000-9FFF, U+ff??;
}

L'utilizzo di sottoinsiemi di intervalli Unicode e file separati per ogni variante stilistica del carattere consente di definire una famiglia di caratteri composita che è più veloce ed efficiente da scaricare. I visitatori scaricano solo le varianti e i sottoinsiemi di cui hanno bisogno e non sono costretti a scaricare sottoinsiemi che potrebbero non vedere o utilizzare mai nella pagina.

Quasi tutti i browser supportano unicode-range. Per la compatibilità con i browser meno recenti, potrebbe essere necessario utilizzare la "sottoimpostazione manuale". In questo caso, devi ricorrere a una singola risorsa del carattere che contenga tutti i sottoinsiemi necessari e nascondere il resto al browser. Ad esempio, se la pagina utilizza solo caratteri latini, puoi rimuovere gli altri glifi e pubblicare quel determinato sottoinsieme come risorsa autonoma.

  1. Determina quali sottoinsiemi sono necessari:
    • Se il browser supporta i sottoinsiemi di intervalli Unicode, seleziona automaticamente il sottoinsieme corretto. La pagina deve solo fornire i file del sottoinsieme e specificare intervalli Unicode appropriati nelle regole @font-face.
    • Se il browser non supporta i sottoinsiemi di intervalli Unicode, la pagina deve nascondere tutti i sottoinsiemi non necessari, ovvero lo sviluppatore deve specificare i sottoinsiemi richiesti.
  2. Genera sottoinsiemi di caratteri:
    • Utilizza lo strumento pyftsubset open source per sottoinserire e ottimizzare i caratteri.
    • Alcuni server di caratteri, come Google Font, eseguiranno automaticamente il sottoinsieme per impostazione predefinita.
    • Alcuni servizi di caratteri consentono la sottosezione manuale tramite parametri di query personalizzati, che puoi utilizzare per specificare manualmente il sottoinsieme richiesto per la tua pagina. Consulta la documentazione del fornitore del carattere.

Selezione e sintesi dei caratteri

Ogni famiglia di caratteri può essere composta da più varianti stilistiche (normale, grassetto, corsivo) e da più spessori per ogni stile. Ognuno di questi, a sua volta, può contenere forme di glifi molto diverse, ad esempio spaziature, dimensioni o forme diverse.

Spessori dei caratteri

Il diagramma riportato sopra illustra una famiglia di caratteri che offre tre diversi spessori in grassetto:

  • 400 (regolare).
  • 700 (in grassetto).
  • 900 (grassetto extra).

Tutte le altre varianti intermedie (indicate in grigio) vengono mappate automaticamente alla variante più vicina dal browser.

Quando viene specificato un peso per il quale non esiste un volto, viene utilizzato un volto con un peso simile. In generale, i caratteri in grassetto corrispondono a quelli con un peso maggiore e i caratteri in corsivo a quelli con un peso minore.

Algoritmo di corrispondenza dei caratteri CSS

Una logica simile si applica alle varianti in corsivo. Il designer del carattere controlla quali varianti verranno prodotte e tu controlli quali utilizzare nella pagina. Poiché ogni variante è un download separato, è consigliabile mantenere basso il numero di varianti. Ad esempio, puoi definire due varianti in grassetto per la famiglia Carattere fantastico:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 700;
  src: local('Awesome Font'),
       url('/fonts/awesome-l-700.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

L'esempio precedente dichiara la famiglia di caratteri Carattere fantastico, composta da due risorse che coprono lo stesso insieme di glifi latini (U+000-5FF), ma offrono due "pesi" diversi: normale (400) e grassetto (700). Tuttavia, cosa succede se una delle regole CSS specifica un'altra dimensione del carattere o imposta la proprietà font-style su italic?

  • Se non è disponibile una corrispondenza esatta dei caratteri, il browser sostituisce la corrispondenza più simile.
  • Se non viene trovata alcuna corrispondenza stilistica (ad esempio, nell'esempio precedente non sono state dichiarate varianti in corsivo), il browser sintetizza la propria variante di carattere.
Sintesi dei caratteri

L'esempio riportato sopra illustra la differenza tra i risultati del carattere reale e quelli sintetizzati per Open Sans. Tutte le varianti sintetizzate vengono generate da un singolo carattere con spessore 400. Come puoi vedere, c'è una differenza notevole nei risultati. I dettagli su come generare le varianti in grassetto e oblique non sono specificati. Di conseguenza, i risultati variano da un browser all'altro e dipendono molto dal carattere.

Elenco di controllo per l'ottimizzazione delle dimensioni dei caratteri web

  • Controlla e monitora l'utilizzo dei caratteri:non utilizzare troppi caratteri nelle tue pagine e, per ogni carattere, riduci al minimo il numero di varianti utilizzate. In questo modo, puoi offrire un'esperienza più coerente e veloce ai tuoi utenti.
  • Se possibile, evita i formati precedenti: i formati EOT, TTF e WOFF sono più grandi di WOFF 2.0. EOT e TTF sono formati strettamente non necessari, mentre WOFF potrebbe essere accettabile se devi supportare Internet Explorer 11. Se scegli come target solo i browser moderni, l'opzione più semplice e con il rendimento migliore è utilizzare solo WOFF 2.0.
  • Sottoinsieme delle risorse dei caratteri:molti caratteri possono essere sottoinsiemi o suddivisi in più intervalli Unicode per fornire solo i glifi richiesti da una determinata pagina. In questo modo, le dimensioni del file vengono ridotte e la velocità di download della risorsa migliora. Tuttavia, quando definisci i sottoinsiemi, assicurati di ottimizzare per il riutilizzo dei caratteri. Ad esempio, non scaricare un insieme di caratteri diverso, ma sovrapposto, su ogni pagina. Una buona prassi è creare sottoinsiemi in base allo script: ad esempio, latino e cirillico.
  • Dai la precedenza a local() nell'elenco src: se inserisci local('Font Name') per primo nell'elenco src, le richieste HTTP non verranno effettuate per i caratteri già installati.
  • Utilizza Lighthouse per verificare la compressione del testo.

Effetti su Largest Contentful Paint (LCP) e Cumulative Layout Shift (CLS)

A seconda dei contenuti della pagina, i nodi di testo possono essere considerati candidati per Largest Contentful Paint (LCP). È quindi fondamentale assicurarsi che i caratteri web siano il più piccoli possibile seguendo i consigli riportati in questo articolo, in modo che gli utenti vedano il testo nella pagina il prima possibile.

Se temi che, nonostante i tuoi sforzi di ottimizzazione, il testo della pagina possa richiedere troppo tempo per essere visualizzato a causa di una risorsa di caratteri web di grandi dimensioni, la proprietà font-display dispone di una serie di impostazioni che possono aiutarti a evitare il testo invisibile durante il download di un carattere. Tuttavia, l'utilizzo del valore swap potrebbe causare variazioni significative del layout che influiscono sul Cumulative Layout Shift (CLS) del tuo sito. Se possibile, valuta la possibilità di utilizzare i valori optional o fallback.

Se i tuoi caratteri web sono fondamentali per il tuo branding e, di conseguenza, per l'esperienza utente, valuta la possibilità di precaricarli in modo che il browser abbia un vantaggio nella loro richiesta. In questo modo puoi ridurre sia il periodo di scambio se utilizzi font-display: swap sia il periodo di blocco se non utilizzi font-display: swap.font-display