Guides / Typography
font_download

Google Fonts Performance: Load Fonts Fast

Google Fonts is convenient, but the default embed code is slow. Two round trips to external servers, render-blocking behavior, and no caching control can add 300–600ms to your LCP. Here's how to load fonts fast — or eliminate the cost entirely.

April 2026 · 9 min read

The Default Embed (and Its Problems)

Google's standard embed code is a render-blocking stylesheet that triggers two external DNS lookups before a single character renders on screen.




Step 1: Add preconnect Hints

preconnect warms up the TCP connection and TLS handshake for external domains before the browser parses the <link> tag. This alone saves 100–200ms on cold loads.








Step 2: Always Use display=swap

font-display: swap tells the browser to render text in a system font immediately, then swap to the custom font when it loads. Without this, browsers may show blank text (FOIT — Flash of Invisible Text) for up to 3 seconds.

/* Without display=swap */
@font-face {
  font-family: 'Inter';
  /* browser default: auto — may hide text for up to 3s */
}

/* With display=swap (what &display=swap adds in the URL) */
@font-face {
  font-family: 'Inter';
  font-display: swap; /* show system font → swap when loaded */
}

/* Other values:
   font-display: block    → 3s invisible, then swap (worst for UX)
   font-display: fallback → 100ms invisible, 3s swap window
   font-display: optional → 100ms invisible, no swap (best perf, skip if slow)
*/

Step 3: Request Only the Weights You Need

Every weight is a separate font file download. Request only what you actually use — common mistake is including 8 weights when the design uses 2.








Step 4: Use Variable Fonts

Variable fonts contain ALL weights and styles in a single file. One request instead of many. Google Fonts automatically serves variable fonts when you request a weight range.




/* Now use any weight without extra downloads */
h1 { font-weight: 800; }
p  { font-weight: 400; }
strong { font-weight: 600; }

/* Variable font axes (if the font supports them) */
.heading {
  font-variation-settings: 'wght' 750, 'ital' 0;
}

Step 5: Self-Host for Maximum Control

Self-hosting eliminates the external DNS lookup entirely and gives you full control over caching headers. Use google-webfonts-helper.herokuapp.com to download the font files and CSS.

/* Self-hosted setup (after downloading from google-webfonts-helper) */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/inter-v13-latin-regular.woff2') format('woff2');
  /* woff2 is supported in all modern browsers — no fallback needed */
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/inter-v13-latin-700.woff2') format('woff2');
}

/* Preload the most critical font file */

Performance Comparison

MethodDNS LookupsRender BlockingCache ControlLCP Impact
Default Google Fonts2 (googleapis + gstatic)YesGoogle controlsHigh
+ preconnect + swap2 (warmed up)No (swap)Google controlsMedium
+ variable font2 (warmed up)No (swap)Google controlsLow-Medium
Self-hosted0 (same origin)No (swap)Full controlVery Low

Common Google Fonts Mistakes

  • No preconnect to fonts.gstatic.com — most guides only show the googleapis preconnect but font files come from gstatic.com. Both are needed.
  • Missing crossorigin on the gstatic preconnect — without crossorigin, the preconnect hint is ignored for font file requests.
  • Requesting unused weights — check your CSS and use the minimum required (usually just 400 and 700).
  • Loading fonts in CSS @import instead of HTML link — @import is blocking inside a stylesheet. Always use the HTML tag.
  • Not preloading the hero font — if your above-the-fold text uses a custom font, preload it with <link rel=preload> to eliminate the LCP penalty.

Frequently Asked Questions

Does Google Fonts share user data?
Google Fonts logs IP addresses for abuse protection purposes. For GDPR-strict sites, self-hosting eliminates this concern entirely, as no requests go to Google's servers.
What is FOUT vs FOIT?
FOUT (Flash of Unstyled Text) = system font shown briefly, then replaced by custom font. FOIT (Flash of Invisible Text) = no text shown until custom font loads. FOUT with font-display: swap is preferable — users can read content immediately.
Is woff2 the only format I need?
For modern browsers (2020+), yes — woff2 has 97%+ support. The old pattern of serving woff, ttf, and eot fallbacks is unnecessary for any site targeting modern browsers.
How do I check if my font is render-blocking?
Run a Lighthouse audit in Chrome DevTools and look for 'Eliminate render-blocking resources'. Google PageSpeed Insights will also flag it. The Network waterfall in DevTools shows font request timing.

Free reference

The 47 Tools Cheat Sheet

One printable page with every tool on this site, what it does, and when to reach for it. Free. It asks for an email so Gumroad can send you the file, unlike the tools themselves.