Ottimizza il caricamento e il rendering dei caratteri web

Ilya Grigorik
Ilya Grigorik

Un carattere web "completo" che include tutte le varianti stilistiche, di cui potresti non avere bisogno, oltre a tutti i glifi, che potrebbero rimanere inutilizzati, può facilmente generare un download di più megabyte. In questo post scoprirai come ottimizzare il caricamento dei caratteri web in modo che i visitatori scarichino solo ciò che utilizzeranno.

Per risolvere il problema dei file di grandi dimensioni contenenti tutte le varianti, la regola CSS @font-face è stata specificamente progettata per consentirti di suddividere la famiglia di caratteri in una raccolta di risorse. ad esempio sottoinsiemi Unicode e varianti di stile distinte.

Alla luce di queste dichiarazioni, il browser determina i sottoinsiemi e le varianti richiesti e scarica l'insieme minimo necessario per visualizzare il testo, il che è molto pratico. Tuttavia, se non fai attenzione, potrebbe anche creare un collo di bottiglia delle prestazioni nel percorso di rendering critico e ritardare il rendering del testo.

Il comportamento predefinito

Il caricamento lento dei caratteri comporta un'importante implicazione nascosta che può ritardare il rendering del testo. Il browser deve creare l'albero di rendering, che dipende dalle strutture DOM e CSSOM, prima di sapere di quali risorse carattere sono necessarie per il rendering del testo. Di conseguenza, le richieste di caratteri subiscono un notevole ritardo dopo altre risorse critiche e il browser potrebbe non visualizzare il testo fino al recupero della risorsa.

Percorso di rendering critico per i caratteri

  1. Il browser richiede il documento HTML.
  2. Il browser inizia ad analizzare la risposta HTML e a creare il DOM.
  3. Il browser rileva CSS, JS e altre risorse e invia le richieste.
  4. Il browser crea il codice CSSOM dopo aver ricevuto tutti i contenuti CSS e lo combina con l'albero DOM per creare l'albero di rendering.
    • Le richieste di caratteri vengono inviate dopo che l'albero di rendering indica quali varianti di caratteri sono necessarie per visualizzare il testo specificato nella pagina.
  5. Il browser esegue il layout e mostra i contenuti sullo schermo.
    • Se il carattere non è ancora disponibile, il browser potrebbe non visualizzare i pixel del testo.
    • Quando il carattere è disponibile, il browser colora i pixel del testo.

La "gara" tra la prima visualizzazione dei contenuti della pagina, che può essere eseguita poco dopo la creazione dell'albero di rendering, e la richiesta della risorsa font è ciò che crea il "problema di testo vuoto", in cui il browser potrebbe eseguire il rendering del layout della pagina ma omettere qualsiasi testo.

Precaricando i caratteri web e usando font-display per controllare il comportamento dei browser in presenza di caratteri non disponibili, puoi evitare pagine vuote e variazioni del layout dovute al caricamento dei caratteri.

Precarica le risorse webFont

Se è molto probabile che la tua pagina abbia bisogno di un WebFont specifico ospitato su un URL che conosci in anticipo, puoi sfruttare la priorità delle risorse. L'utilizzo di <link rel="preload"> attiverà una richiesta per WebFont all'inizio del percorso di rendering critico, senza dover attendere la creazione del CSSOM.

Personalizza il ritardo di rendering del testo

Sebbene il precaricamento renda più probabile che un carattere web sia disponibile quando viene visualizzato i contenuti di una pagina, non offre garanzie. Devi comunque considerare il comportamento dei browser durante il rendering di testo che utilizza un font-family, che non è ancora disponibile.

Nel post Evita testo invisibile durante il caricamento dei caratteri puoi vedere che il comportamento predefinito del browser non è coerente. Tuttavia, puoi indicare ai browser moderni come vuoi che si comportino utilizzando font-display.

Supporto dei browser

  • 60
  • 79
  • 58
  • 11.1

Fonte

Analogamente ai comportamenti di timeout dei caratteri esistenti implementati da alcuni browser, font-display segmenta la durata del download di un carattere in tre periodi principali:

  1. Il primo punto è il periodo di blocco dei caratteri. Durante questo periodo, se il tipo di carattere non viene caricato, qualsiasi elemento che tenti di utilizzarlo deve invece essere visualizzato con un tipo di carattere di riserva invisibile. Se il tipo di carattere viene caricato correttamente durante il periodo di blocco, verrà utilizzato normalmente.
  2. Il periodo di scambio dei caratteri si verifica subito dopo il periodo di blocco dei caratteri. Durante questo periodo, se il tipo di carattere non viene caricato, qualsiasi elemento che tenti di utilizzarlo deve essere visualizzato con un tipo di carattere di riserva. Se il tipo di carattere viene caricato correttamente durante il periodo di scambio, verrà utilizzato normalmente.
  3. Il periodo di errore dei caratteri si verifica immediatamente dopo il periodo di scambio dei caratteri. Se il volto del carattere non viene ancora caricato all'inizio di questo periodo, viene contrassegnato come caricamento non riuscito, causando il normale utilizzo di caratteri di riserva. In caso contrario, il carattere viene utilizzato normalmente.

Comprendere questi periodi significa che puoi usare font-display per decidere come deve essere visualizzato il tuo carattere in base a quando è stato scaricato o a quando è stato scaricato.

Per utilizzare la proprietà font-display, aggiungila alle tue regole @font-face:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  font-display: auto; /* or block, swap, fallback, optional */
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

font-display supporta attualmente il seguente intervallo di valori:

  • auto
  • block
  • swap
  • fallback
  • optional

Per ulteriori informazioni sul precaricamento dei caratteri e sulla proprietà font-display, vedi i seguenti post:

L'API Font Load

Se utilizzati insieme, <link rel="preload"> e CSS font-display ti offrono un notevole controllo sul caricamento e sul rendering dei caratteri, senza aggiungere ulteriori costi. Se, però, hai bisogno di ulteriori personalizzazioni e vuoi sostenere l'overhead associato all'esecuzione di JavaScript, hai a disposizione un'altra opzione.

L'API Caricamento caratteri fornisce un'interfaccia di scripting per definire e gestire i tipi di caratteri CSS, monitorare l'avanzamento del download ed eseguire l'override del comportamento predefinito di caricamento lento. Ad esempio, se hai la certezza che sia necessaria una determinata variante del carattere, puoi definirla e indicare al browser di avviare un recupero immediato della risorsa carattere:

Supporto dei browser

  • 35
  • 79
  • 41
  • 10

Fonte

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden,
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here...
});

Inoltre, poiché puoi controllare lo stato dei caratteri (tramite il metodo check()) e monitorare l'avanzamento del download, puoi anche definire una strategia personalizzata per il rendering del testo nelle tue pagine:

  • Puoi mantenere premuto il rendering di tutto il testo finché il carattere non diventa disponibile.
  • Puoi implementare un timeout personalizzato per ogni carattere.
  • Puoi usare il carattere di riserva per sbloccare il rendering e inserire un nuovo stile che utilizzi il carattere desiderato quando sarà disponibile.

L'aspetto migliore è che puoi anche combinare le strategie illustrate sopra per i diversi contenuti della pagina. Ad esempio, puoi ritardare il rendering del testo in alcune sezioni finché il carattere non è disponibile, utilizzare un carattere di riserva ed eseguire di nuovo il rendering al termine del download del carattere.

È necessario eseguire correttamente la memorizzazione nella cache

Le risorse dei caratteri sono, in genere, risorse statiche che non vengono aggiornate spesso. Di conseguenza, sono particolarmente adatti per una lunga scadenza massima: assicurati di specificare sia un'intestazione ETag condizionale sia un criterio Cache-Control ottimale per tutte le risorse dei caratteri.

Se la tua applicazione web utilizza un service worker, la pubblicazione delle risorse dei caratteri con una strategia cache-first è appropriata per la maggior parte dei casi d'uso.

Non dovresti archiviare i caratteri utilizzando localStorage o IndexedDB, ognuno di questi ha un proprio insieme di problemi di prestazioni. La cache HTTP del browser fornisce il meccanismo migliore e più solido per distribuire le risorse dei caratteri al browser.

Elenco di controllo per il caricamento dei caratteri web

  • Personalizza il caricamento e il rendering dei caratteri utilizzando <link rel="preload">, font-display o l'API Font Loading: il comportamento di caricamento lento predefinito potrebbe causare ritardi nel rendering del testo. Queste funzionalità della piattaforma web consentono di ignorare questo comportamento per caratteri specifici e di specificare strategie di rendering e timeout personalizzate per i diversi contenuti della pagina.
  • Specifica criteri di riconvalida e di memorizzazione nella cache ottimale: i caratteri sono risorse statiche che vengono aggiornate raramente. Assicurati che i tuoi server forniscano un timestamp di durata massima di lunga durata e un token di riconvalida per consentire un riutilizzo efficiente dei caratteri tra pagine diverse. Se utilizzi un service worker, è appropriata una strategia basata sulla cache.

Test automatici per il comportamento di caricamento di WebFont con Lighthouse

Lighthouse può aiutarti ad automatizzare il processo per assicurarti di seguire le best practice per l'ottimizzazione dei caratteri web.

I seguenti controlli possono aiutarti ad assicurarti che le tue pagine continuino a seguire le best practice per l'ottimizzazione dei caratteri web nel tempo: