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, due semplici variabili determinano la dimensione di un particolare file di caratteri: la complessità dei percorsi vettoriali di ogni glifo e il numero di glifi in un determinato carattere. Ad esempio, Open Sans, uno dei caratteri web 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 mira a supportare tutte le lingue del mondo. Tieni presente, tuttavia, che le dimensioni totali di Noto, incluse tutte le lingue, comportano il download in formato ZIP o più di 1,1 GB.

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

Formati dei caratteri web

Oggi sul web vengono consigliati due formati di contenitori per i caratteri:

WOFF e WOFF 2.0 godono di un'ampia adozione 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, fornisci lo WOFF come riserva.
  • In alternativa, puoi evitare di utilizzare i caratteri web per i browser precedenti e utilizzare i caratteri di sistema. Questa opzione può essere più efficace anche per i dispositivi più vecchi e più vincolati.
  • 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.

Considera l'uso di 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é caricare gli stili normale e in grassetto più le relative versioni in corsivo, puoi caricare un singolo file contenente tutte le informazioni. Tuttavia, le dimensioni variabili dei file dei caratteri saranno maggiori di quelle di una singola variante, anche se inferiori rispetto alla 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.

Ora i caratteri variabili sono supportati da tutti i browser moderni. Per saperne di più, consulta Introduzione ai caratteri variabili sul web.

Seleziona il formato corretto

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 sua volta, ogni descrittore src contiene un elenco prioritario e separato da virgole di varianti della risorsa:

  • La direttiva local() ti consente di fare riferimento, caricare e utilizzare i caratteri installati localmente. Se l'utente ha già installato il font nel sistema, questa operazione bypassa completamente la rete e diventa il più veloce.
  • L'istruzione 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 determina che il carattere è necessario, esegue l'iterazione dell'elenco di risorse fornito 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 delle definizioni esterne:
    • Se è presente un suggerimento per il formato, il browser verifica se lo supporta prima di avviare il download. Se il browser non supporta il suggerimento, il browser 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 di latino, cirillico e greco) 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 di intervalli (ad es. U+400-4ff): indica i punti di codice iniziale e finale di un intervallo
  • Intervallo di caratteri jolly (ad esempio U+4??): ? 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 la creazione di sottoinsiemi di intervalli Unicode, selezionerà automaticamente il sottoinsieme giusto. La pagina deve solo fornire i file del sottoinsieme e specificare gli 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:
    • Usa lo strumento open source Pyftsubset per creare un sottoinsieme e ottimizzare i tuoi caratteri.
    • Alcuni server di caratteri, come Google Font, eseguiranno automaticamente il sottoinsieme per impostazione predefinita.
    • Alcuni servizi per i caratteri consentono l'assegnazione secondaria manuale tramite parametri di query personalizzati, che puoi utilizzare per specificare manualmente il sottoinsieme richiesto per la 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 (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 tratto più spesso, mentre i caratteri in corsivo corrispondono a quelli con un tratto più sottile.

Algoritmo di corrispondenza dei caratteri CSS

Una logica simile si applica alle varianti in corsivo. Il designer del carattere controlla le varianti prodotte, mentre tu stabilisci quali varianti utilizzerai 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 una corrispondenza stilistica (ad esempio, nell'esempio precedente non sono state dichiarate varianti in corsivo), il browser sintetizza la propria variante del carattere.
Sintesi dei caratteri

L'esempio precedente illustra la differenza tra i risultati effettivi e sintetizzati per i caratteri 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. Pertanto, 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 può 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.
  • Sottoponi le risorse carattere:molti caratteri possono essere sottoinsiemi o suddivisi in più intervalli Unicode per pubblicare 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, fai attenzione a ottimizzarli 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 della 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 può causare variazioni significative del layout che influiscono sulla Cumulative Layout Shift (CLS) del 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 possa iniziare prima a richiederli. 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.