ESC

Type to search the knowledge base.

Resource Hints preload prefetch

dns-prefetch, preconnect, preload, prefetch, modulepreload — when each helps LCP/navigation and how to avoid over-fetching.

intermediate3 min read
  • javascript
  • resource-hints

The network is often the long pole. Resource hints tell the browser what you’ll need soon so it can open connections or fetch early — or they waste bandwidth if you lie. These are mostly HTML/<link> (and HTTP Link headers), orchestrated from frontend architecture.

The menu

Hint Intent Priority vibe
dns-prefetch Resolve DNS early cheap
preconnect DNS + TCP + TLS medium cost
preload Fetch now for current navigation high — competes with critical assets
prefetch Likely next navigation low
modulepreload ES module graph for current page high for modules
<link rel="dns-prefetch" href="https://cdn.example.com" />
<link rel="preconnect" href="https://api.example.com" crossorigin />

<link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/hero.avif" as="image" fetchpriority="high" />

<link rel="modulepreload" href="/assets/main.js" />

<link rel="prefetch" href="/next-page-data.json" as="fetch" crossorigin />

preload rules of thumb

  • Only critical current-page resources (LCP image, render-blocking font you definitely use).
  • as must match how it’ll be consumed or the browser may double-fetch.
  • Fonts need crossorigin even when same-origin (anonymous CORS mode for fonts).
  • Over-preloading fights with your real critical CSS/JS budget.
// dynamic preload for LCP discovered late
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'image';
link.href = lcpUrl;
document.head.appendChild(link);

prefetch for next page

<link rel="prefetch" href="/product/42" />

Good after hover/intent on SPA route targets or pagination “next.” Browsers deprioritize; still don’t prefetch huge videos for every user on 2G.

In SPAs, data prefetch on link hover is often better in JS (fetch + cache) than blind full document prefetch.

preconnect budget

Each preconnect costs sockets and CPU. Cap to a few critical origins (CDN, API, font host). dns-prefetch alone is cheaper when you only need DNS.

CDNs and servers can send Link: </app.css>; rel=preload; as=style before HTML finishes. Same semantics; earlier on slow TTFB paths.

Measuring

Use Lighthouse/WebPageTest: did LCP improve, or did you just download more? Watch unused preloads warnings in Chrome.

Interview answer (out loud)

“dns-prefetch and preconnect warm origins; preload fetches critical current navigation assets with correct as; modulepreload is for the module graph; prefetch is speculative for the future. I preload sparingly for LCP and fonts, preconnect only key origins, and verify with performance tools so hints don’t steal bandwidth.”

as values that matter

Common as tokens: script, style, image, font, fetch, document. Wrong as can make the preload unusable and waste the download.

<link rel="preload" href="/app.js" as="script" />
<link rel="preload" href="/app.css" as="style" />

fetchpriority

<link rel="preload" as="image" href="hero.jpg" fetchpriority="high" />

Helps LCP competition among images; still don’t mark everything high.

SPA route prefetch example

link.addEventListener('pointerenter', () => {
  import('./pages/Settings.js'); // module prefetch via dynamic import
}, { once: true });

Complements <link rel=prefetch> for code-split chunks.

Further reading

Related guides