Hai passato ore a scegliere il typeface perfetto per il tuo negozio. Le etichette del menu utilizzano un sans-serif personalizzato che corrisponde esattamente al tuo brand. Ma ogni volta che testi il negozio su mobile, vedi un flash di testo invisibile dove il menu dovrebbe apparire, seguito da uno shift di layout quando il font finalmente si carica. Il tuo punteggio CLS è 0.18, che Google contrassegna come “necessita miglioramenti”, e sospetti che il font del menu sia il colpevole.
Il problema non è il font stesso. Il problema è il modo in cui il browser gestisce il caricamento dei font. Per impostazione predefinita, la maggior parte dei browser nasconde il testo fino a quando i font personalizzati terminano il download, il che può richiedere 300-800 millisecondi su una connessione mobile lenta. L’area del menu rimane vuota, la pagina sembra rotta, e quando il font finalmente appare, sposta tutto ciò che si trova sotto. Questo danneggia sia l’LCP (perché il contenuto significativo è ritardato) che il CLS (perché il layout si muove).
Questo articolo spiega le cinque strategie font-display, quale funziona meglio per i menu di navigazione, e come implementare il caricamento dei font senza rovinare il tuo brand o i tuoi Core Web Vitals.
- I browser nascondono il testo durante il download dei font per impostazione predefinita, causando Flash of Invisible Text (FOIT).
font-displaycontrolla se il testo appare immediatamente o attende il font personalizzato.font-display: swapè la scelta migliore per il testo del menu—mostra il fallback immediatamente, effettua lo swap quando pronto.- I font di sistema (già installati sul dispositivo) hanno costo di caricamento zero ed eliminano completamente FOIT/FOUT.
- Il precaricamento dei font può ridurre il ritardo ma non elimina il rischio di shift di layout.
I due problemi del caricamento font: FOIT e FOUT
Quando un browser incontra un font web personalizzato, deve decidere cosa fare con il testo che utilizza quel font mentre il file del font è ancora in corso di download. Ci sono due comportamenti possibili, ognuno con i suoi compromessi.
Flash of Invisible Text (FOIT)
Il browser nasconde il testo fino a quando il font si carica. Lo spazio del testo è riservato, ma non appare nulla. Se il font impiega 500 millisecondi per il download, l’utente guarda lo spazio vuoto per mezzo secondo. Questo è il comportamento predefinito nella maggior parte dei browser.
FOIT è negativo per l’LCP perché il contenuto di testo significativo non è visibile fino al caricamento del font. È anche negativo per l’usabilità—gli utenti non riescono a leggere il menu, il che potrebbe fargli pensare che la pagina sia rotta.
Flash of Unstyled Text (FOUT)
Il browser mostra il testo immediatamente utilizzando un font di fallback (solitamente un font di sistema come Arial o Helvetica), quindi passa al font personalizzato una volta caricato. Il testo è leggibile subito, ma lo swap può causare uno shift di layout se il font di fallback e il font personalizzato hanno dimensioni diverse.
FOUT è migliore per l’LCP (il testo appare immediatamente) ma può danneggiare il CLS se non gestito con attenzione. La chiave è far corrispondere le dimensioni del font di fallback al font personalizzato il più possibile.
Le cinque strategie font-display
La proprietà CSS font-display controlla il modo in cui i browser gestiscono il periodo di caricamento dei font. Ci sono cinque possibili valori, ognuno con un tempismo e un comportamento di fallback diversi.
| Valore | Comportamento | Migliore per |
|---|---|---|
auto |
Il browser decide (solitamente FOIT per 3 secondi, poi FOUT) | Non consigliato—imprevedibile |
block |
FOIT per fino a 3 secondi, quindi swap | Testo decorativo dove il font del brand è critico |
swap |
FOUT immediatamente—mostra il fallback, effettua swap quando pronto | Testo del corpo, menu di navigazione |
fallback |
FOIT per 100ms, poi FOUT per 3s, quindi rimani con il fallback | Titoli dove il font conta ma la velocità conta di più |
optional |
FOIT per 100ms, poi usa il fallback se il font non è pronto, mai effettuare swap | Testo critico per le performance |
Per i menu di navigazione, font-display: swap è quasi sempre la scelta giusta. Rende il menu leggibile immediatamente (buono per l’LCP e l’usabilità) ed effettua lo swap al font del brand non appena si carica (buono per la coerenza del brand). Il rischio è lo shift di layout, che affronteremo tra un momento.
Come utilizzare font-display nel tuo stylesheet
Se il tuo font è definito nel tuo CSS utilizzando @font-face, aggiungi la proprietà font-display:
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brandfont.woff2') format('woff2');
font-display: swap;
}
.menu-link {
font-family: 'BrandFont', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
Lo stack font-family è importante. Elenca il tuo font personalizzato per primo, quindi i font di sistema come fallback. Questo assicura che il testo del menu appaia istantaneamente in un font di sistema, quindi effettui lo swap al tuo font personalizzato quando si carica.
Se il tuo font è caricato da Google Fonts, aggiungi il parametro display=swap all’URL:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap">
Google Fonts inietta automaticamente font-display: swap nel CSS generato.
Prevenire lo shift di layout con la corrispondenza del font di fallback
Il problema con font-display: swap è che se il font di fallback e il font personalizzato hanno dimensioni o spaziatura diverse, il testo rifluisce quando lo swap accade, causando uno shift di layout. Questo è particolarmente evidente nei menu di navigazione, dove anche un piccolo spostamento può spostare l’intero contenuto della pagina.
La soluzione è regolare il font di fallback per corrispondere alle dimensioni del font personalizzato utilizzando le proprietà size-adjust, ascent-override e descent-override. Questi sono caratteristiche CSS relativamente nuove (supportate in tutti i browser moderni a partire dal 2024) che ti permettono di modificare un font di fallback per corrispondere a un font personalizzato.
Ecco un esempio:
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brandfont.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'BrandFont Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 95%;
descent-override: 25%;
}
.menu-link {
font-family: 'BrandFont', 'BrandFont Fallback', Arial, sans-serif;
}
La proprietà size-adjust scala il font di fallback in modo che la sua x-height corrisponda al font personalizzato. Le proprietà ascent-override e descent-override regolano la spaziatura verticale.
Trovare i valori giusti richiede test. Strumenti come Fallback Font Generator di Simon Hearne automatizzano questo processo. Inserisci il tuo font personalizzato e lo strumento calcola i valori di override ottimali per i font di sistema comuni.
La corrispondenza dei font di fallback in questo modo riduce il CLS dallo swap dei font a quasi zero. Il testo continua a effettuare lo swap dal fallback al font personalizzato, ma il layout non si sposta perché le dimensioni sono identiche.
Font di sistema: l’alternativa a costo zero
Il font più veloce è nessun font in assoluto—o piuttosto, un font di sistema già installato sul dispositivo dell’utente. I font di sistema hanno costo di download zero, costo di parsing zero e rischio di shift di layout zero.
Ecco uno stack di font di sistema moderno che ha un bell’aspetto su tutte le piattaforme:
.menu-link {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif;
}
Questo ti dà:
- San Francisco su macOS e iOS
- Segoe UI su Windows
- Roboto su Android
- Impostazioni predefinite appropriate per la piattaforma su Linux
I font di sistema non sono così distintivi come i typeface personalizzati, ma sono puliti, leggibili e ottimizzati per le loro piattaforme. Molti siti ad alto traffico (GitHub, Medium, WordPress.com) utilizzano i font di sistema per motivi di performance.
Se le tue linee guida del brand richiedono un font personalizzato, considera di utilizzare i font di sistema per il menu di navigazione e di riservare il font personalizzato per i titoli, il testo hero, o il body copy dove ha più impatto visivo. Il menu è UI funzionale. Non ha bisogno di portare il brand pesantemente come fa un titolo.
Precaricamento dei font per ridurre la durata del FOUT
Anche con font-display: swap, c’è un ritardo tra l’apparizione del fallback e lo swap del font personalizzato. Su una connessione lenta, questo può essere 500 millisecondi o più. Il precaricamento del file del font dice al browser di recuperarlo con priorità alta all’inizio del caricamento della pagina, il che riduce il ritardo dello swap.
<link rel="preload" href="/fonts/brandfont.woff2" as="font" type="font/woff2" crossorigin>
L’attributo crossorigin è obbligatorio anche se il font è ospitato sul tuo dominio, perché i font vengono recuperati con la modalità CORS.
Il precaricamento non elimina il FOUT, ma riduce la durata. Se il tuo font del menu è piccolo (sotto i 50KB) ed è critico per il brand, il precaricamento può migliorare le performance percepite.
Attenzione: Il precaricamento compete con altre risorse critiche come CSS e JavaScript. Precarica solo i font utilizzati above the fold e veramente essenziali. Il precaricamento di troppe risorse può rallentare il rendering iniziale.
Font di icone vs SVG inline
Molti menu di navigazione utilizzano font di icone (Font Awesome, Remix Icon, Material Icons) per frecce, icone di ricerca e icone di hamburger. I font di icone sono solo font, quindi hanno le stesse caratteristiche di caricamento dei font di testo: FOIT per impostazione predefinita, rischio di shift di layout e costo di download (spesso 50-150KB per un font di icone completo).
SVG inline è una scelta migliore per le icone del menu. Un SVG inline fa parte dell’HTML, quindi appare immediatamente senza richiesta di rete e senza ritardo di caricamento dei font. Scala perfettamente e supporta lo styling CSS.
Ecco un esempio:
<button class="menu-toggle" aria-label="Open menu">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</button>
Questa icona di hamburger è 200 byte. Un font di icone completo con 2.000 icone che non userai mai è 150KB. SVG inline elimina anche il problema FOIT—l’icona appare istantaneamente perché fa parte dell’HTML.
Le app di menu moderne come Navi+ utilizzano SVG inline per tutte le icone, il che è uno dei motivi per cui evitano i problemi di shift di layout che affliggono i menu basati su font di icone.
Caricamento di font specifico per Shopify
I temi Shopify in genere caricano i font in uno dei tre modi: da Google Fonts, dalla CDN di Shopify (tramite il selettore di font delle impostazioni del tema) o da file di font personalizzati nella cartella assets del tema.
Google Fonts
Se il tuo tema utilizza Google Fonts, assicurati che il parametro display=swap sia nell’URL. Cerca in theme.liquid una riga come questa:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600">
Cambiala in:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap">
Font CDN Shopify
Se il tuo tema utilizza il selettore di font integrato di Shopify (Settings > Typography), Shopify serve i font dalla sua CDN e include automaticamente font-display: swap a partire dal 2023. Non devi fare nulla.
File di font personalizzati
Se hai caricato file di font personalizzati nella cartella assets del tuo tema, aggiungi font-display: swap alla dichiarazione @font-face nel tuo CSS.
Misurare l’impatto del caricamento dei font
Usa Chrome DevTools per vedere come i font influenzano il tuo LCP e CLS.
Verifica FOIT
Apri DevTools, vai alla scheda Network, filtra per “Font” e ricarica la pagina. Osserva l’area del menu. Se il testo del menu è invisibile per un periodo notevole prima di apparire, hai FOIT. Aggiungi font-display: swap per correggerlo.
Verifica lo shift di layout
Apri DevTools, vai alla scheda Performance, fai clic su Record, ricarica la pagina e interrompi la registrazione. Cerca nella sezione Experience le barre rosse “Layout Shift”. Fai clic su una per vedere quali elementi si sono spostati. Se il testo del menu è elencato, lo swap del font ha causato uno shift di layout. Usa la corrispondenza dei font di fallback per correggerlo.
Misura CLS
Esegui un test Lighthouse (in DevTools o PageSpeed Insights). Guarda il punteggio CLS e la diagnostica “Evita grandi spostamenti di layout”. Se i font sono elencati come causa, hai bisogno di una migliore corrispondenza di fallback o dovresti considerare il passaggio a font di sistema.
Vittoria veloceSe il tuo menu utilizza un font personalizzato e stai vedendo problemi di CLS, prova a passare a uno stack di font di sistema come test. Esegui di nuovo Lighthouse. Se il CLS diminuisce significativamente, il font personalizzato era il problema. Puoi quindi decidere se il valore del brand del font personalizzato vale il costo delle performance, o implementare la corrispondenza dei font di fallback per ottenere entrambi.
Come appare il caricamento di un buon font del menu
Un menu di navigazione ben ottimizzato gestisce i font in uno dei due modi.
Opzione 1: Font di sistema. Nessun font personalizzato, costo di download zero, FOIT zero, shift di layout zero. Il menu appare istantaneamente con testo dall’aspetto nativo.
.menu-link {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
Opzione 2: Font personalizzato con swap e corrispondenza di fallback. Il testo del menu appare immediatamente in un font di sistema, quindi effettua lo swap al font personalizzato senza shift di layout.
@font-face {
font-family: 'BrandFont';
src: url('/fonts/brandfont.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'BrandFont Fallback';
src: local('Arial');
size-adjust: 107%;
}
.menu-link {
font-family: 'BrandFont', 'BrandFont Fallback', Arial, sans-serif;
}
Entrambi gli approcci risultano in un menu che è leggibile entro il primo secondo di caricamento della pagina, che è ciò che misura l’LCP. Il primo approccio è più semplice e più veloce. Il secondo approccio preserva la coerenza del brand con un costo minimo per le performance.
Per le icone, usa SVG inline invece di font di icone. Le icone appaiono istantaneamente, scalano perfettamente e costano poche centinaia di byte invece di 150KB.
La maggior parte dei negozi che passano dal caricamento font predefinito (FOIT, nessuna corrispondenza di fallback) a uno di questi modelli vedono il CLS diminuire di 0,05-0,15 punti e l’LCP migliorare di 200-400 millisecondi su mobile. Il menu sembra lo stesso all’utente, ma il browser lo renderizza più velocemente e più agevolmente.
Questo articolo fa parte della guida più ampia su Menu e LCP: come la navigazione rallenta il tuo largest contentful paint.