Resource hints overview
Five resource hints — dns-prefetch, preconnect, preload, modulepreload, prefetch — cover every stage of the request lifecycle. Pick the right one for the job.
What it is
Resource hints are <link rel> declarations that tell the browser to do work earlier than the HTML parser would otherwise discover it. The W3C Resource Hints specification defines four; HTML adds two more (preload, modulepreload).
| Hint | What it does | Use when |
|---|---|---|
dns-prefetch | Resolve DNS for the origin. | Cheap fallback for older browsers; large numbers of secondary origins. |
preconnect | DNS + TCP + TLS handshake to the origin. | You will definitely request from this origin in the next ~10 seconds. |
preload | Fetch a specific resource at high priority. | Late-discovered critical resource (LCP image, font referenced from CSS). |
modulepreload | Fetch and parse an ES module, including its dependency graph. | Critical JS module that would otherwise be discovered after the parser hits <script type="module">. |
prefetch | Fetch a resource at low priority for a future navigation. | The user’s next likely page (article → comments, search → first result). |
Why it matters
The browser’s parser discovers resources in source order. Anything referenced from CSS, JavaScript, or a late <link> is found late, after several round-trips. Hints move discovery to the start of the document so work overlaps with the rest of HTML parsing.
Used wrongly, hints harm performance — preloading 20 things slows the LCP element because everything fights for the same bandwidth. Treat each hint as a deliberate decision.
How to implement
A practical decision flow:
-
Is this for the current page?
- Yes → next question.
- No, it’s the next navigation →
prefetch(asdocumentfor HTML, otherwise blank).
-
Is it a specific URL the browser would otherwise discover late?
- Yes, and it’s an ES module →
modulepreload. - Yes, anything else →
preloadwith the correctas=(image, font, style, script, fetch). - No, you don’t know the URL yet but you know the origin → next question.
- Yes, and it’s an ES module →
-
How many requests will you make to that origin?
- 1+ — use
preconnect(withcrossoriginif the requests use CORS). - 0–1 maybe — use
dns-prefetchonly. Cheaper.
- 1+ — use
Example head with each hint serving a distinct purpose:
<!-- We'll request the hero from the CDN -->
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<!-- Analytics may or may not fire on this page -->
<link rel="dns-prefetch" href="https://stats.example.com">
<!-- Font is referenced from CSS, would be discovered late -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<!-- LCP image, eager loading + high priority -->
<link rel="preload" href="/hero.avif" as="image" fetchpriority="high">
<!-- Critical module imported by /app.mjs -->
<link rel="modulepreload" href="/router.mjs">
<!-- After the user reads this article they often hit the next one -->
<link rel="prefetch" href="/articles/next" as="document">
See preload-prefetch-preconnect for syntax details and gotchas.
Common mistakes
- Preloading the same resource that is already referenced by a
<link rel="stylesheet">higher in the head. The preload scanner finds it; the hint is noise. - Mixing
preloadandprefetchsemantics.preloadis for the current page;prefetchis for the next one. - Forgetting
crossoriginon font preloads or preconnects to CORS origins. modulepreloadon a non-module script. Usepreload as="script"for classic scripts.- More than ~5 hints in the head. Each one competes for bandwidth.
Verification
- DevTools → Network → check the start time and priority of hinted resources. Hints should pull them left.
- Chrome console logs unused preloads after a few seconds.
- Lighthouse “Preload key requests” and “Preconnect to required origins” cover the common cases.
Related topics
Sources & further reading
- W3C — Resource Hints — W3C
- MDN — <link>: The External Resource Link element — MDN
- web.dev — Preload critical assets — web.dev
- MDN — rel=modulepreload — MDN