<link rel="preload"> for fonts is one of those recommendations that gets copy-pasted from performance checklists without the context of when it actually helps. It's a priority signal, not a free speed boost — and used carelessly, it competes with the resources that matter more for your actual load metrics.
What Preload Actually Does
rel="preload" tells the browser "fetch this resource early and at high priority, before the browser would otherwise discover it by parsing CSS." For fonts, that means starting the font file download before the browser has even finished parsing the stylesheet that references it via @font-face, which normally wouldn't kick off until CSS parsing reaches that rule.
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
The crossorigin attribute is mandatory even for same-origin font files — fonts are always fetched in anonymous mode per spec, and omitting crossorigin on the preload tag causes the browser to fetch the resource twice (once for the preload, once for the actual font request, because they're treated as different cache entries). This double-fetch bug is one of the most common ways preload accidentally makes things worse rather than better — see the web.dev guidance on font preloading for the full breakdown.
Where It Genuinely Helps
If you have a custom font used for large above-the-fold text — a hero heading, for instance — and you're using font-display: block or otherwise want that text to appear in the correct font as early as possible rather than flashing a fallback, preload gives the font request a head start that can measurably shorten the window where text is invisible or in the wrong font. This is the textbook case preload was designed for.
Where It Actively Hurts
Competing With Your LCP Image
Browsers allocate early bandwidth and connection priority to a limited set of resources. If your actual Largest Contentful Paint element is a hero image, not text, then preloading a font file is pulling bandwidth and priority away from the resource your Core Web Vitals score actually depends on. A preloaded font that isn't render-blocking or LCP-relevant is, in this scenario, pure overhead — it starts an early download for a resource that wasn't the bottleneck, at the expense of one that was.
Preloading Fonts You Don't Use Above the Fold
It's common to see every font weight in a design system preloaded "just in case" — regular, medium, semibold, bold, italic — when only one or two of those actually render in the initial viewport. Each additional preloaded font is a full download competing for the same early-priority slot:
<!-- Overkill: preloading five weights when only one renders above the fold -->
<link rel="preload" href="/fonts/inter-regular.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/inter-medium.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/inter-semibold.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/inter-bold.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/inter-italic.woff2" as="font" type="font/woff2" crossorigin>
Trim this to the one or two weights that actually appear above the fold on first paint. Weights used further down the page, or only on hover/interaction states, don't need early priority — let them load through the normal CSS discovery path.
When font-display: swap Already Handles It Well
If you're using font-display: swap, the browser shows a fallback font immediately and swaps to the web font once it arrives — there's no invisible-text period to shorten. In that setup, preload mainly affects how quickly the visual swap happens, which is a much smaller win than eliminating an invisible-text window, and often not worth the bandwidth tradeoff against your LCP image. Preload earns its keep more clearly with font-display: block or optional, where the timing of that first font byte has a more direct effect on what the user sees.
Preloading a Font Not Actually Used on the Page
Copy-pasted <head> boilerplate across templates is a common source of this — a preload tag pointing at a font file that a particular page variant doesn't even reference. Chrome will warn about this in DevTools console ("was preloaded using link preload but not used"), and it's pure wasted bandwidth with zero benefit.
Decision Point: Preload or Not
| Situation | Preload the font? |
|---|---|
| Above-the-fold heading uses font-display: block, custom font is the primary visual anchor | Yes — this is the case preload is for |
| Page's LCP element is an image, not text | No, or only after confirming the image itself isn't preload-starved |
| Using font-display: swap with an acceptable fallback font match | Usually skip — the swap already minimizes perceived delay |
| Font weight used only below the fold or on interaction | No — let normal CSS discovery handle it |
| System font stack, no custom web font | N/A — nothing to preload |
Checking Whether It's Actually Helping
Don't guess — use the DevTools Network panel's priority column to confirm the font is actually being fetched at high priority as intended, and check the Performance panel's LCP breakdown to see if your LCP candidate's load delay increased after adding font preloads. If the LCP element is an image and its load delay phase got worse after you added a font preload, that's a direct signal the preload is stealing priority from the resource that matters more — in that case, size and compress the image properly with the Image Resizer first, and reconsider whether the font needs preload at all.
Treat preload as a scalpel for one specific bottleneck, not a checklist item to apply uniformly. A page with zero preloaded fonts and a well-optimized LCP image will usually beat a page with five preloaded font weights fighting each other and the hero image for the same early bandwidth.