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.
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.
| Problem | Potential Effect |
|---|---|
| Large font files | Longer download time |
| Too many font weights | Additional network requests and data |
| Poor fallback font | Visible layout changes |
| Invisible text strategy | Text may appear late |
| No caching | Fonts may be downloaded repeatedly |
| Unnecessary preload | Important resources can compete for bandwidth |
| Missing font-display | Browser 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.
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 Variant | Use Only If Needed |
|---|---|
| 400 Regular | Normal body text |
| 500 Medium | Medium-weight interface text |
| 600 Semibold | Navigation or emphasized text |
| 700 Bold | Strong headings |
| Italic variants | Only 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.
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.
| Value | General Behavior |
|---|---|
| swap | Show fallback text and replace it when the web font loads |
| block | Temporarily hide text while waiting for the font |
| fallback | Short wait followed by fallback behavior |
| optional | Allows 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.
| Approach | Result |
|---|---|
| Full font | Contains many character sets |
| Latin subset | Contains common Latin characters |
| Custom subset | Contains only required characters |
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.
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.
| Approach | Advantages | Considerations |
|---|---|---|
| Self-hosted | Control over files, caching and optimization | Requires managing font assets |
| External provider | Simple setup and large font libraries | Adds 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, immutableLong-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 Area | Possible Font Impact |
|---|---|
| LCP | Large text may depend on a delayed font |
| CLS | Fallback and final fonts may have different metrics |
| Visual stability | Text can reflow when fonts change |
| Network performance | Font 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.
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.
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 performanceFont Loading Audit
| Check | Question |
|---|---|
| Format | Are fonts delivered in an efficient modern format? |
| Weights | Are all downloaded weights actually used? |
| Subsetting | Does the font contain unnecessary characters? |
| Fallback | Is the fallback visually and metrically appropriate? |
| font-display | Is text rendering behavior intentional? |
| Preload | Are only critical fonts preloaded? |
| Caching | Are static font files cached effectively? |
| Families | Are unnecessary font families removed? |
| Layout | Does the font swap cause visible movement? |
| Testing | Has 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.