Font Chargement

Comment web font chargement affecte Core Web Vitals comme CLS et LCP, font-display strategies, preloading fonts, et reducing layout shift depuis font swaps.

Première publication : 2 juil. 2026 · Dernière mise à jour : 3 août 2026 · Avancé

Custom web fonts sont external fichiers que ont à download avant texte peut rendre dans les, donc le navigateur nécessite a plan pour ce que à montrer dans le meantime. Que plan — définir mainly par le CSS font-display property — moves deux Core Web Vitals: LCP (quand a rendre-blocking font delays votre largest texte) et CLS (quand swapping le fallback pour le web font shifts le layout). Le deux par défaut behaviors, FOIT et FOUT, chaque ont a échec mode. Le fiable corrections: preload critical fonts, utiliser font-display: optional or swap deliberately, match votre fallback font's metrics, or skip custom fonts entirely. c’est pas a direct facteur de classement — il feeds CLS/LCP, qui sont page experience signaux.

TL;DR — Custom web fonts sont rendre-affecting external resources. Ils hit LCP quand a rendre-blocking font delays votre largest texte element, et CLS quand le fallback-à-web-font swap reflows le layout. Le deux par défaut behaviors — FOIT (invisible jusqu’à chargé) et FOUT (fallback alors swap) — chaque échouer differently. font-display est le principal lever (swap guarantees FOUT; optional donne a ~100ms window et alors commits, killing le plus tard swap). Preloading corrections late font discovery; preload + font-display: optional est le combo Google’s propre engineering singled out pour eliminating layout jank. Mais passing le Lighthouse font-display vérifier ne fait pas corriger CLS — que nécessite a metrically-matched fallback (or size-adjust/ascent-override overrides). None de ce est a direct facteur de classement; il feeds CLS/LCP, qui sont page experience signaux.

Preuve à l’appui de cette affirmation The CSS Font Loading API exposes font loading state and control to documents. Portée : Current official or standards documentation. Niveau de confiance : élevé · Vérifié : MDN: CSS Font Loading API Preuve à l’appui de cette affirmation font-display controls how a font face is displayed while it downloads and when fallback is used. Portée : Current official or standards documentation. Niveau de confiance : élevé · Vérifié : MDN: font-display

Pourquoi fonts are a special cas

«Most performance problems are about bytes — an image is too big, a script blocks the main thread. Fonts are worse than that in one specific way: they’re an external resource and they change the metrics of your text. So a font can hurt you two different ways at once. It can delay when text paints (an LCP problem), and it can change the size and shape of that text after it’s already on screen (a CLS problem). » (Traduction) (Résumé en français de la section dix-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Le deux par défaut navigateur behaviors sont worth naming parce que le entier topic hangs off les:

  • FOIT (Flash de Invisible Texte): texte dans le custom font est rendu invisible jusqu’à le font charge or a timeout est hit — historically up à a ~3-deuxième bloquer dans la plupart navigateurs.
  • FOUT (Flash de Unstyled Texte): le fallback font montre immédiatement, alors obtient swapped pour le web font une fois il charge.

FOIT feels “cleaner” (aucun jump) mais risques a rendu delay. FOUT feels faster (texte maintenant) mais risques a layout shift on swap. Aucun est automatiquement sûr — c’est le core idea à hold sur.

Il aussi aide à séparé le pipeline dans distinct stages, parce que success à un stage ne fait pas guarantee success à le suivant. A @font-face règle seulement declares a face — le navigateur récupère le réel font fichier seulement une fois matching styled texte on lune page exige il (declaration et matching sont séparé étapes depuis le récupérer). Que récupérer est subject à CORS si le font est servi cross-origin, donc a stylesheet que charge cleanly ne fait pas guarantee le font réponse itself carries le correct cross-origin permission — a manquant header là fails silently as a font que jamais renders. Et a successful récupérer encore ne fait pas guarantee a stable-looking page: cold-cache, warm-cache, et déjà-cached font states peut produce différent discovery et swap timing, donc testing un repeat page charger dans DevTools ne fait pas tell vous ce que a premier-time visitor en réalité voit.

How fonts affecter LCP

Si le largest visible element on votre page est texte — a big headline, a hero paragraph — alors le font que texte utilise peut become partie de votre LCP chemin. Per web.dev’s LCP guidance, le LCP resource de une page, si il a un, va être soit an image or a web font. A rendre-blocking font que laisse que texte invisible (FOIT) pushes votre LCP out jusqu’à le font arrives.

Le corriger ici est straightforward et comes straight depuis Google. On web.dev’s Optimize Plus grand affichage de contenu guide:

«> *“If you set a font-display value of anything other than auto or block, then

text will always be visible during load, and LCP won’t be blocked on an additional network request.”* — web.dev » (Traduction) (Résumé en français de la section vingt-sept, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

En d’autres termes: swap, fallback, or optional tout garder text visible during charger, so votre LCP isn’t hostage to the font requête.

How fonts affecter CLS

CLS comes depuis le swap. Votre fallback font et votre web font presque jamais ont identical character widths et line heights, donc quand le navigateur remplace un avec le autre, le texte reflows — et tout ci-dessous il moves. c’est a layout shift.

Le counterintuitive partie, et le chose la plupart personnes miss: FOIT causes CLS aussi. Même invisible texte est encore laid out en utilisant le fallback font’s metrics, donc le swap encore moves choses. Depuis web.dev’s Optimize Décalage cumulatif de mise en page guide:

«> *“Both approaches can cause layout shifts. Even if the text is invisible, it’s

still laid out using the fallback font, so when the web font loads, the text block and the surrounding content shift”* — web.dev » (Traduction) (Résumé en français de la section trente-deux, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Le même page frames le deux behaviors plainly:

«> *“The fallback font is swapped with the web font, incurring a Flash of Unstyled

Text (FOUT). ‘Invisible’ text is displayed using the fallback font until a web font is available and the text is made visible (FOIT—flash of invisible text).”* — web.dev » (Traduction) (Résumé en français de la section trente-quatre, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

j’ai said le même chose dans plainer terms dans mon Ahrefs écrire-up on Décalage cumulatif de mise en page: quand a font charge or changements, vous fin up avec a noticeable shift — a FOIT or a FOUT. c’est un de le la plupart courant real-world CLS causes, correct alongside images sans dimensions et contenu injected après charger.

The font-display property

font-display est a @font-face descriptor que contrôle deux windows: le bloquer period (comment long le navigateur hides texte waiting pour le font) et le swap period (comment long, après le bloquer period, il va encore swap dans le web font une fois il arrives). Per web.dev’s Meilleur Practices pour Fonts:

ValeurBlock periodSwap period
autoBrowser-dependentBrowser-dependent
block2–3 secondsInfinite
swap0msInfinite
fallback100ms3 seconds
optional100msNone

«MDN’s font-display reference, which Google’s own docs link to as the spec source, describes them tersely: swap gives an extremely small block period and an infinite swap period; optional gives an extremely small block period and no swap period. That “no swap period” is the whole point of optional — after the block period window closes, whatever font is in use stays, so there’s no later swap to shift the layout. » (Traduction) (Résumé en français de la section trente-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Un caution on le numbers dans que tableau: le CSS specification itself seulement defines bloquer/swap period categories — court, extremely petit, infinite, none — et laisse le exact duration à le navigateur. Le millisecond/deuxième figures ci-dessus sont web.dev’s documented Chromium behavior, pas a cross-navigateur guarantee. Treat les as illustrative plutôt que a spec promise, et vérifier actuel numbers pour whichever navigateur/version vous êtes en réalité testing contre.

Qui valeur pour qui contenu? web.dev’s propre advice est que ces peut être mixed: utiliser swap pour branding et autre visually distinctive elements (où seeing le brand font matters et a brief shift est acceptable), et optional pour corps texte (où CLS-sensitivity wins et vous’d plutôt pas shift). c’est a genuinely utile règle de thumb — ne pas appliquer un valeur site-wide par reflex.

Preloading fonts

Font requêtes sont découvert late. Le navigateur ne fait pas know il nécessite a font jusqu’à il a parsed votre CSS, matched a @font-face règle à an element on lune page, et decided que element est visible. Seulement alors fait il commencer le download. A <link rel="preload"> court-circuits que:

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

Que indique le navigateur à commencer fetching le font immédiatement, dans parallel avec tout sinon, au lieu de waiting à découvrir il. Bing’s engineering team décrit exactly ce mechanism on leur propre recherche pages (plus dans le Citations tab): le preload balises dans le <head> kick off le font downloads correct away, whereas sans les le navigateur ne ferait pas récupérer le fonts jusqu’à il avait parsed le CSS et trouvé matching elements.

Le strongest combination per Google’s propre writeup est preload + font-display: optional. web.dev’s Empêcher layout shifting et FOIT par preloading optional fonts calls combining <link rel="preload"> avec font-display: optional le la plupart effective façon à guarantee aucun layout jank quand rendu custom fonts, et notes que Chrome (depuis version 83) eliminated le layout shifting que utilisé à se produire quand preloading optional fonts. Le preload donne le font son meilleur shot à arriving à l’intérieur le ~100ms window; optional guarantees que si il ne fait pas, vous ne pas pay pour il avec a shift.

Quand pas à preload. Preloading n’est pas gratuit. web.dev warns que preload est highly effective à making fonts discoverable early, mais il comes à le coût de taking navigateur resources away depuis chargement autre resources. Preload le un or deux fonts vous en réalité besoin ci-dessus le fold — preloading chaque font weight vous propre peut starve plus important resources et faire lune page slower overall.

Assurez-vous le preload en réalité obtient reused. A preload seulement aide si le navigateur peut match il à le réel font requête — le href, as="font", type, et crossorigin mode tout ont à line up avec ce que le CSS @font-face règle ends up requesting, or vous’ll obtenir an “unused preload” warning et a wasted deuxième download au lieu de a faster un. Preloading peut aussi bypass unicode-range selection, pulling bas a subset vous n’a pas en réalité besoin pour que page. Confirmer le match dans DevTools’ Network panel: vous vouloir à voir un requête pour que font, kicked off par le preload, pas deux.

Fixing le shift itself: fallback metric matching

Ici’s le trap: passing le Lighthouse font-display vérifier fait pas corriger CLS. Google’s Lighthouse docs sont explicit que FOIT et FOUT ont le même impact on CLS une fois le custom font remplace le temporary système font. Donc swap rend votre texte visible (bon pour LCP et pour le “invisible text” audit) mais laisse le swap shift dans placer.

À kill le shift quand a swap fait se produire, vous ont à faire le fallback font et le web font prendre up le même space. Deux levers:

  1. Pick a metrically-similar système fallback dans votre font-family stack, plutôt que a unique custom font nom avec rien sensible behind il. Le closer le fallback’s character widths et line height sont à le web font, le plus petit le shift.
  2. Override le web font’s metrics avec size-adjust, ascent-override, descent-override, et line-gap-override on le @font-face règle, donc le web font est forced à match le fallback’s box. web.dev listes ces descriptors, et Smashing Magazine’s deep dive on CSS font descriptors walks via les dans detail si vous vouloir à go tout le façon.

Chaque de ceux four descriptors adjusts a différent metric, et actuel navigateur prise en charge varies par descriptor — vérifier compatibility avant leaning on quelconque unique un. Valider contre le réel weights, styles, et scripts vous ship, aussi: a corriger confirmed on votre regular-weight Latin texte ne fait pas guarantee bold, italic, or a non-Latin script behave le même façon.

DebugBear’s Fixing Layout Shifts Caused by Web Fonts is a bon end-to-end walkthrough of ce: mesurer the impact, identifier the problem font, appliquer font-display, choisir a meilleur fallback, alors adjust font metrics.

Google Fonts vs. self-hosting

Vous ne pas ont à self-host à contrôler font-display. Le Google Fonts CSS2 API accepts a display requête parameter — https://fonts.googleapis.com/css2?family=Roboto&display=swap sets font-display directement on le servi @font-face règles. Addy Osmani’s post on shipping font-display à Google Fonts covers le modifier: previously le seulement façon à specify font-display pour Google Fonts était à self-host les, et ce supprimé que besoin.

Self-hosting encore wins on un chose: il eliminates le supplémentaire DNS lookup et connection à fonts.googleapis.com et fonts.gstatic.com. c’est a réel latency coût, et un de le raisons a preconnect resource hint à ceux origins aide si vous faire utiliser Google Fonts. Weigh le connection overhead contre le convenience — et ne pas assume “c’est depuis Google, donc c’est fine.” A copy-pasted Google Fonts embed est encore a rendre-blocking stylesheet requête plus a font requête, et older embeds peut pas carry a display valeur à tout.

«There’s no universal winner between the two options — it comes down to which scripts and weights you actually ship, your caching setup, and the font’s license terms. Run the comparison against your own pages rather than defaulting to whichever one a tutorial recommended. » (Traduction) (Résumé en français de la section cinquante-huit, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Variable fonts

A variable font packs nombreux weights et styles (regular, bold, condensed, italic) dans a unique fichier avec adjustable axes. Que peut être a net win — un requête à la place de six — si vous en réalité utiliser plusieurs de ceux variants. Mais a complet variable font est a bigger unique fichier que un static weight, donc si vous seulement ever rendre un weight, shipping le entier variable font peut être slower, pas faster. Subset il à le axes et characters vous utiliser, servir il as WOFF2 donc c’est compressed, et vérifier le font’s license — pas chaque foundry permits subsetting or self-hosting.

Reducing the fichier in the premier placer

Tout ci-dessus manages quand le font charge. Vous pouvez aussi shrink ce que charge. Font subsetting strips out glyphs vous ne pas utiliser (an tous-Latin site ne fait pas besoin Cyrillic et CJK ranges), et WOFF2 est le well-compressed format à servir. A plus petit font fichier est plus probable à arrive à l’intérieur optional’s window et moins probable à bloquer LCP — subsetting et compression sont le complementary lever à font-display et preload, pas an alternative à les.

il y a aucun unique “correct” subset or universal byte-savings percentage ici, though — il dépend on le scripts, characters, et weights votre spécifique public en réalité nécessite. A number vous saw dans quelqu’un else’s cas study or benchmark n’est pas a promise pour votre pages; mesurer votre propre font requêtes avant et après.

Is ce a ranking factor?

Être precise ici. Font chargement est pas a direct facteur de classement. Ce que il affecte est CLS et LCP, qui sont Core Web Vitals et partie de Google’s page experience signaux. Et page experience est a lightweight, tiebreaker-style signal — pertinence et qualité dominate; il aide decide entre sinon comparable résultats, pas entre a great page et a poor un. Donc le honest framing est: corriger votre font chargement parce que c’est a genuine utilisateur-experience problème que se produit à feed deux classement inputs — pas parce que a font-display valeur va déplacer vous up le résultats on son propre.

My propre prendre

À travers mon Ahrefs CLS et LCP guides j’ai landed on le même priority order, et il encore holds. Si vous pouvez utiliser a système font, faire que — il y a rien à charger, donc là sont aucun delays or changements que causer a shift. Si vous ont à utiliser a custom font, le actuel meilleur méthode pour minimizing CLS est à combine <link rel="preload"> (grab le font as soon as possible) avec font-display: optional (donner il a petit window à charger); si il ne fait pas faire il dans temps, lune page simplement montre a par défaut font, et votre custom font obtient mis en cache et montre up on subsequent charge. Preload, alors optional, alors — meilleur de tout — simplement ne pas utiliser a custom font. c’est le entier ladder.

Ajouter une note d’expert

Épingler une citation d’expert

Nouvelle personne ? Créez son profil non revendiqué à /admin/experts/ → Épingler une citation d’expert d’abord.