Skip to content

Chapter 8: The Font Fiasco: Optimizing Web Font Loading

Of course. After optimizing our main assets, let's turn to an often-overlooked element that directly impacts how quickly users can see your content: Web Fonts.


The Scenario 📝

  • System: A website that uses a custom font, loaded from an external service like Google Fonts, to match its branding and design.
  • Problem: When users load the page, they experience one of two frustrating phenomena:
    1. FOIT (Flash of Invisible Text): The space where the text should be is completely blank for a few seconds, and then the text suddenly appears.
    2. FOUT (Flash of Unstyled Text): The text appears immediately in a default system font (like Times New Roman), and then abruptly "jumps" to the custom font once it finishes loading, causing a jarring layout shift.

Analyzing the Bottleneck 🧐

The bottleneck here is Render-Blocking. By default, browsers will often refuse to "paint" text pixels on the screen until the corresponding font file has been completely downloaded. This has a severe impact on the First Contentful Paint (FCP) metric. The user perceives the site as slow because they can't read anything.


Font Optimization Techniques

1. Use font-display: swap

This is the most important and easiest technique to apply.

  • The Logic: font-display is a CSS property that lets you tell the browser how to behave while a font is loading.
  • How to do it: Add font-display: swap; to your @font-face block.
    css
    @font-face {
      font-family: 'My Custom Font';
      src: url('/fonts/my-font.woff2') format('woff2');
      font-weight: 400;
      font-style: normal;
      font-display: swap; /* <--- Add this line */
    }
  • The Result: The browser will display the text immediately using a fallback system font. Once the custom font has downloaded, it will be "swapped" in. FOUT is considered a much better user experience than FOIT.

2. Self-Host Your Fonts

  • The Issue: Using third-party services like Google Fonts requires the browser to make an additional DNS and HTTP connection to another domain, which adds latency.
  • The Solution: Download the font files (in a modern format like .woff2) and store them on the same server as your website.
  • The Result: Reduced latency because the browser doesn't need to establish a new connection.

3. Preload Critical Fonts

  • The Issue: The browser typically only discovers that it needs to download a font file after it has already downloaded and parsed the CSS file.
  • The Solution: You can give the browser a "heads-up" by adding a <link rel="preload"> tag to the <head> of your HTML file.
    html
    <link rel="preload" href="/fonts/my-font.woff2" as="font" type="font/woff2" crossorigin>
  • The Result: This tag instructs the browser to start downloading this font file with a high priority right away, in parallel with other assets, making it available sooner.

How Nuxt Handles This ✨

  • Modules like @nuxtjs/google-fonts for Nuxt often automatically apply best practices like adding font-display: swap for you.
  • To self-host, you can place your font files in the public/ directory and declare your @font-face rules in a global CSS file.

Conclusion:

  • Optimizing font loading is crucial for ensuring users can see your text content as quickly as possible.
  • Always use font-display: swap to avoid the "flash of invisible text."
  • Consider self-hosting and preloading your most critical fonts to minimize latency.