Ctrl + K
Performance17 min read

Font Loading Best Practices

Learn how to load web fonts efficiently with font-display, preloading, font subsetting, modern formats, fallbacks, caching and performance best practices.

Published: 2026-09-02

Web fonts can significantly improve the visual design of a website, but they also introduce additional network requests and rendering work. A poorly configured font can delay text rendering, cause visible layout changes and increase the amount of data required before a page becomes fully usable.

Font loading optimization is therefore an important part of frontend performance. The goal is not simply to make fonts load faster, but to make text remain readable, minimize layout shifts and ensure that the browser downloads only the font resources that are actually needed.

Font Loading Checklist

  • Use modern web font formats such as WOFF2.
  • Load only the font weights and styles that are actually used.
  • Use font-display to control rendering behavior.
  • Choose a suitable fallback font stack.
  • Use font subsetting when appropriate.
  • Preload only critical fonts.
  • Avoid loading unnecessary font families.
  • Cache static font files efficiently.
  • Use font-display: swap or another intentional strategy.
  • Match fallback and web font metrics when possible.
  • Avoid excessive font weights.
  • Test fonts on slow connections and mobile devices.

Why Font Loading Matters

When a page uses a custom web font, the browser may need to download the font before text can be rendered in that font. Depending on the loading strategy, users may temporarily see fallback text, invisible text or text that changes size after the custom font becomes available.

These effects are especially noticeable when a large heading, navigation menu or other prominent text uses a custom font. A delayed font can affect the visual appearance of the page and may contribute to layout instability when the fallback and final fonts have different metrics.

ProblemPotential Effect
Large font filesLonger download time
Too many font weightsAdditional network requests and data
Poor fallback fontVisible layout changes
Invisible text strategyText may appear late
No cachingFonts may be downloaded repeatedly
Unnecessary preloadImportant resources can compete for bandwidth
Missing font-displayBrowser behavior may not match the intended UX

Use WOFF2

WOFF2 is the preferred format for most modern web font deployments because it provides efficient compression and broad browser support. Using an appropriate web font format can substantially reduce the amount of data required compared with older formats.

@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
}

Older formats such as WOFF, EOT and legacy TrueType or OpenType files may still appear in older projects, but they are generally unnecessary for modern websites unless specific compatibility requirements exist.

💡 Prefer WOFF2 for modern websites and avoid shipping multiple legacy font formats unless your browser support requirements actually require them.

Load Only the Weights You Need

Every font weight and style can represent another resource that the browser may need to download. A project that uses regular, medium, semibold, bold and several italic variants can quickly accumulate a large amount of font data.

Font VariantUse Only If Needed
400 RegularNormal body text
500 MediumMedium-weight interface text
600 SemiboldNavigation or emphasized text
700 BoldStrong headings
Italic variantsOnly when italic text is actually used

Before adding a font file, inspect the design system and determine which weights are actually required. If a website only uses regular and bold text, loading five additional weights provides little value while increasing resource usage.

Use font-display

The font-display descriptor controls how the browser handles text while a web font is loading. It allows developers to choose whether text should remain invisible temporarily, immediately use a fallback font, or switch to the web font under specific timing conditions.

@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans.woff2") format("woff2");
  font-display: swap;
}

font-display: swap

The swap value allows the browser to display text using a fallback font while the web font downloads. Once the custom font becomes available, the browser can replace the fallback with the web font.

This strategy prioritizes text visibility. Users can read the content immediately instead of waiting for the custom font, although a visible font change may occur if the fallback and final fonts have substantially different metrics.

font-display: block

The block value can cause text to remain invisible for a short period while the browser waits for the web font. If the font is not available quickly enough, the browser can fall back to another font.

⚠️ Avoid invisible text unless there is a strong design reason for it. For most content-focused websites, keeping text readable during font loading is more useful than hiding it while waiting for a custom font.

font-display: fallback

The fallback value provides a short period for the custom font to become available and then uses the fallback font if it is not ready. It is a compromise between waiting for the preferred font and displaying fallback text immediately.

font-display: optional

The optional value gives the browser more freedom to decide whether the web font should be used. This can be useful when the font is not essential to the page and performance should take priority over guaranteeing that the custom font is displayed.

ValueGeneral Behavior
swapShow fallback text and replace it when the web font loads
blockTemporarily hide text while waiting for the font
fallbackShort wait followed by fallback behavior
optionalAllows the browser to prioritize performance

Choose a Good Fallback Font

A fallback font is not just a backup for broken font requests. It is part of the normal rendering process when font-display: swap or similar strategies are used. The fallback should therefore be selected deliberately.

body {
  font-family: "Example Sans", Arial, sans-serif;
}

The fallback should ideally have a similar visual appearance and character width to the primary font. A large difference between the fallback and final font can cause text to reflow when the web font arrives.

Reduce Layout Shifts From Fonts

A fallback font and a web font can have different character widths, line heights and vertical metrics. When the browser replaces one with the other, text may wrap differently and surrounding elements can move.

This is especially noticeable for large headings and navigation elements. Choosing a metric-compatible fallback reduces the amount of visual movement during the transition.

Use Font Metric Overrides

CSS provides font metric descriptors such as size-adjust, ascent-override, descent-override and line-gap-override. These can be used to make a fallback font behave more like the final web font.

@font-face {
  font-family: "Adjusted Fallback";
  src: local("Arial");
  size-adjust: 98%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

Metric overrides require testing because incorrect values can produce unexpected text sizing or spacing. They are most useful when reducing layout changes between a fallback font and a known web font.

Subset Fonts

Font files can contain thousands of glyphs that a website never uses. Font subsetting creates a smaller font containing only the required character ranges.

For example, a website written only in English may not need Cyrillic, Greek or many other character sets. Removing unused glyphs can significantly reduce font size.

ApproachResult
Full fontContains many character sets
Latin subsetContains common Latin characters
Custom subsetContains only required characters
⚠️ Be careful when subsetting multilingual websites. Removing a character range that users actually need can cause missing glyphs or unexpected fallback fonts.

Unicode-Range

The unicode-range descriptor allows different font resources to be associated with specific Unicode character ranges. This can help browsers download only the subset needed for the characters appearing on a page.

@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  unicode-range: U+0000-00FF;
}

Preload Critical Fonts Carefully

A preload hint can tell the browser that a resource is important and should be requested early. This can be useful for a font required immediately for above-the-fold content.

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

Preloading can reduce the time required to discover a critical font, but it should not be used for every font on a website. Each preload consumes network priority and bandwidth that could otherwise be used by HTML, CSS, images or scripts.

💡 Preload only fonts that are genuinely critical to the initial rendering path. If a font is used only below the fold or on another page, it usually does not need to be preloaded globally.

Use crossorigin Correctly

Fonts loaded from a different origin require the appropriate CORS configuration. When preloading a cross-origin font, the crossorigin attribute is important because the preload request must match how the font will later be requested.

Self-Hosted vs External Fonts

Fonts can be hosted directly on your own domain or delivered by an external font provider. Self-hosting gives you greater control over caching, subsetting, file versions and delivery, while external providers can simplify font management.

ApproachAdvantagesConsiderations
Self-hostedControl over files, caching and optimizationRequires managing font assets
External providerSimple setup and large font librariesAdds an external dependency and request

For performance-sensitive websites, self-hosting can make it easier to optimize exactly which font files are delivered. However, the correct choice depends on the project's architecture, provider and deployment requirements.

Avoid Too Many Font Families

Using several font families increases the number of font resources that may need to be downloaded. A design that uses one primary family and one complementary family is generally easier to optimize than a page that loads many unrelated families.

  • Use a primary font family consistently.
  • Limit decorative fonts to places where they provide real value.
  • Avoid loading multiple families when one family provides the required weights.
  • Remove unused fonts from the project.

Create a Font Stack

A font stack defines the preferred font followed by fallback alternatives. A well-designed stack gives the browser reasonable options if the primary font is unavailable or still loading.

:root {
  --font-body:
    "Example Sans",
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
}

System fonts can provide a fast fallback because they are already available on the user's device and do not require an additional network request.

System Fonts as a Performance Option

Not every website needs a custom web font. System font stacks can provide excellent readability without downloading additional font files. For applications where branding does not require a specific typeface, system fonts can simplify the rendering path.

Cache Font Files

Font files are usually static assets and can be cached for long periods when their URLs are versioned. Effective caching allows returning visitors to reuse fonts rather than downloading them repeatedly.

Cache-Control: public, max-age=31536000, immutable

Long-lived caching is particularly effective when filenames contain a content hash. If the font changes, the URL changes and the browser requests the new resource.

Avoid Runtime Font Transformation When Possible

If fonts are transformed, subsetted or converted during every request, the server may perform unnecessary work and increase response time. Generating optimized font files during the build or deployment process is usually more predictable.

Font Loading and Core Web Vitals

Fonts can influence several aspects of perceived and measured performance. A font that delays important text can affect rendering, while differences between fallback and final font metrics can contribute to layout movement.

Metric or AreaPossible Font Impact
LCPLarge text may depend on a delayed font
CLSFallback and final fonts may have different metrics
Visual stabilityText can reflow when fonts change
Network performanceFont files consume bandwidth

Do Not Preload Every Font

Preloading many font files is a common optimization mistake. Developers may preload every weight because fonts are considered important, but this can cause the browser to request resources that are not needed for the initial view.

⚠️ Preload is a prioritization mechanism, not a general-purpose replacement for normal font loading. Too many preload hints can compete with critical CSS, images and other resources.

Use Font Loading APIs When Necessary

The CSS Font Loading API provides JavaScript access to font loading state. It can be useful for applications that need to coordinate UI behavior with font availability, although normal CSS font loading should be preferred when JavaScript is not required.

document.fonts.ready.then(() => {
  document.documentElement.classList.add("fonts-ready");
});

Font-related JavaScript should be used carefully. Adding JavaScript to control basic font rendering can introduce additional complexity and should not block content unnecessarily.

Test Fonts on Slow Connections

A font strategy that looks perfect on a fast development connection may behave very differently on a slower mobile network. Testing under throttled network conditions makes delayed font rendering, layout changes and excessive resource usage easier to identify.

  • Test with a slow mobile connection.
  • Test with an empty browser cache.
  • Test with a warm browser cache.
  • Check the initial text rendering.
  • Watch for layout movement.
  • Inspect font requests in browser developer tools.
  • Verify that only required font files are downloaded.

Inspect the Network Waterfall

Browser developer tools can show when font requests start, how long they take and which resources compete for network bandwidth. The network waterfall can reveal fonts that are loaded too early, requested multiple times or downloaded despite not being needed.

Common Font Loading Mistakes

  • Loading every available font weight.
  • Using outdated font formats without a compatibility requirement.
  • Forgetting to specify font-display.
  • Using a fallback with very different text metrics.
  • Preloading too many fonts.
  • Loading fonts that are only used on specific pages globally.
  • Using several font families without a clear design purpose.
  • Serving unsubsetted font files when only a small character set is needed.
  • Failing to cache static font resources.
  • Using JavaScript for font loading behavior that CSS can handle.
  • Ignoring font-related layout shifts.
  • Testing only on a fast development connection.

Best Practices

  • Prefer WOFF2 for modern web font delivery.
  • Load only the weights and styles that are actually used.
  • Use font-display intentionally.
  • Provide a carefully selected fallback font stack.
  • Use system fonts when a custom typeface is not necessary.
  • Subset fonts when the full character set is not required.
  • Use unicode-range for appropriate font subsets.
  • Preload only critical fonts.
  • Use long-lived caching for versioned font files.
  • Match fallback and web font metrics when possible.
  • Keep the number of font families small.
  • Measure font performance on realistic devices and networks.
💡 The best font-loading strategy is usually the simplest one that provides the required design. A small number of optimized WOFF2 files, a good fallback stack, intentional font-display behavior and effective caching are often more valuable than a complicated font-loading system.

Recommended Font Loading Workflow

A consistent workflow makes font optimization easier to maintain. Start by identifying the fonts actually required by the design, then remove unnecessary variants before optimizing delivery.

Choose font family
      ↓
Remove unused weights
      ↓
Convert to WOFF2
      ↓
Subset required characters
      ↓
Choose fallback font
      ↓
Configure font-display
      ↓
Preload only critical fonts
      ↓
Configure caching
      ↓
Test rendering and layout
      ↓
Measure performance

Font Loading Audit

CheckQuestion
FormatAre fonts delivered in an efficient modern format?
WeightsAre all downloaded weights actually used?
SubsettingDoes the font contain unnecessary characters?
FallbackIs the fallback visually and metrically appropriate?
font-displayIs text rendering behavior intentional?
PreloadAre only critical fonts preloaded?
CachingAre static font files cached effectively?
FamiliesAre unnecessary font families removed?
LayoutDoes the font swap cause visible movement?
TestingHas the strategy been tested on slow connections?

Frequently Asked Questions

What is the best font format for websites?

WOFF2 is generally the preferred format for modern web font delivery because it provides efficient compression and broad browser support.

Should I use font-display: swap?

font-display: swap is a common choice because it allows fallback text to remain visible while the web font loads. The best value depends on the design and whether displaying the custom font is essential.

Should every font be preloaded?

No. Preload should normally be limited to fonts that are critical to the initial rendering path. Preloading unnecessary fonts can consume bandwidth and compete with other important resources.

How many font weights should a website load?

Only the weights and styles that the design actually uses should normally be loaded. Removing unused variants reduces network requests and total font data.

Can fonts cause Cumulative Layout Shift?

Yes. If the fallback and web font have different metrics, text can change size or wrapping when the custom font loads. Choosing a compatible fallback and using font metric overrides when appropriate can reduce this effect.

Are system fonts faster than web fonts?

System fonts are already installed on the user's device, so they do not require an additional font download. They can therefore eliminate font network requests when a custom typeface is not required.

What is font subsetting?

Font subsetting creates a smaller font file containing only selected characters or character ranges. It can substantially reduce download size when a website does not need the complete glyph set.

Helpful Typography Tools

A Font Pair Generator helps create complementary font combinations, a Font Stack Generator builds practical fallback stacks, a CSS Font Face Generator creates @font-face declarations, a Typography Scale Generator helps establish consistent text sizes, and a CSS Formatter makes font-related CSS easier to read and maintain.

Conclusion

Efficient font loading starts with reducing what the browser has to download. Use modern WOFF2 files, remove unused weights, subset fonts when appropriate and avoid unnecessary font families. Then control rendering with font-display, choose a compatible fallback and preload only resources that are genuinely critical.

Font performance should also be considered as part of the complete rendering process. Effective caching, responsive design, metric-compatible fallbacks and realistic testing can prevent fonts from becoming a source of slow rendering or layout instability. A small, intentional font setup is usually easier to maintain and performs better than loading every available variant.

Found an issue?

Found an error, outdated information, or something missing from this article? Let me know through the Contact page.

Your feedback helps improve our articles and keep them accurate and useful.