Preloading Web Fonts with Crossorigin
Preload web fonts with the required crossorigin attribute to avoid double downloads. Learn why fonts always need CORS and how to set up font preloading correctly.
Detailed Explanation
Preloading Web Fonts
Fonts are one of the most impactful resources to preload because they are typically discovered late in the loading process. The browser cannot know which fonts it needs until it has downloaded CSS, parsed it, built the render tree, and determined which characters need to be rendered.
The Font Loading Timeline Without Preload
- Browser downloads HTML
- Browser discovers
<link rel="stylesheet">and downloads CSS - Browser parses CSS and finds
@font-facedeclarations - Browser builds render tree and determines which fonts are actually used
- Only now does the browser start downloading fonts
- Text is invisible (FOIT) or uses fallback font (FOUT) until font loads
Steps 1-4 can take 500ms-2s. Preloading skips directly to downloading the font.
Correct Font Preload Syntax
<link rel="preload" href="/fonts/inter-var.woff2"
as="font" type="font/woff2"
crossorigin="anonymous" />
Every attribute matters:
as="font"— required for correct priority and CSP checkstype="font/woff2"— tells the browser the format so it can skip unsupported formatscrossorigin="anonymous"— mandatory for fonts, even same-origin ones
Why crossorigin Is Always Required for Fonts
This is the single most common mistake with font preloading. Fonts fetched via @font-face always use CORS mode (anonymous), even when served from the same origin. If you preload a font without crossorigin, the browser makes a non-CORS request. When @font-face later needs the font, it makes a separate CORS request because the cached version does not match. Result: the font is downloaded twice.
<!-- WRONG: missing crossorigin causes double download -->
<link rel="preload" href="/fonts/inter.woff2" as="font"
type="font/woff2" />
<!-- CORRECT: crossorigin matches @font-face CORS mode -->
<link rel="preload" href="/fonts/inter.woff2" as="font"
type="font/woff2" crossorigin="anonymous" />
Best Practices for Font Preloading
- Only preload 1-2 fonts — preloading too many fonts wastes bandwidth and delays other critical resources
- Preload the WOFF2 format only — it has the widest browser support and best compression
- Match the exact URL — the preload URL must exactly match the URL in your
@font-facerule - Consider
font-display: swapin your CSS to show fallback text while the font loads
Use Case
A design-focused portfolio site uses a custom display font (800KB WOFF2) for headings. Without preloading, the heading text is invisible for 1.2 seconds while the font downloads. With preload and crossorigin="anonymous", the font download starts 800ms earlier, reducing the invisible text period to under 400ms.