Resource Hints: Preload & Prefetch for Faster Loading
preload
Current-navigation critical assets
- - High priority fetch
- - Overuse can compete with core resources
prefetch
Likely-future navigation
- - Low-priority/speculative
- - May be skipped under contention
preconnect
Critical cross-origin setup
- - DNS + TCP + TLS early
- - Use for truly important origins
dns-prefetch
Lighter warm-up
- - DNS only
- - Lower cost than full preconnect
Core Lens
Hints are priority control. The win comes from loading the right thing early, not preloading everything.
Flow
Resource hints are scheduling hints to the browser network stack. Interview-safe explanations map preload vs prefetch vs preconnect; deeper explanations include priority trade-offs, speculative behavior, and cache/reuse requirements (such as matching attributes and CORS for fonts).
Quick Decision Guide
Quick Guide:
Preload = "Load this now for current page" (high priority) - Fonts, hero images, critical CSS/JS - <link rel="preload" href="font.woff2" as="font" crossorigin>
Prefetch = "Load this for next page" (low priority) - Next page JavaScript, likely navigation targets - <link rel="prefetch" href="/dashboard.js">
Preconnect = "Connect to this domain early" - External APIs, CDNs, third-party domains - <link rel="preconnect" href="https://api.example.com">
Rule: Preload a small number of truly critical resources. Preloading too much defeats the purpose.
Interview-safe vs Deeper Browser Model
Interview-safe model
Use this quick mapping:
preload: fetch for current navigation (high importance)prefetch: fetch for likely future navigation (low priority/speculative)preconnect: set up DNS/TCP/TLS early for critical cross-origin dependenciesdns-prefetch: DNS only, cheaper than preconnectDeeper browser model
For stronger answers, add:
crossorigin on preload for correct reuseas should match resource type so prioritization and reuse work correctlyPractical framing
Resource hints are not speed hacks by default. They are priority control.
Use hints only when you can justify which user-visible bottleneck they remove.
Preload - Critical Resources
What is Preload?
Preload tells browser: "Download this now, I need it soon"
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="hero.jpg" as="image">
<link rel="preload" href="font.woff2" as="font" crossorigin>When to Preload
✅ Critical fonts - Prevents FOUT/FOIT
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>✅ Hero images - Above-the-fold images
<link rel="preload" href="/hero.jpg" as="image">✅ Critical CSS - Required for first paint
<link rel="preload" href="/critical.css" as="style">✅ Critical JavaScript - App initialization code
<link rel="preload" href="/app.js" as="script">Important Attributes
as: Resource type (font, image, script, style, fetch)type: MIME type (font/woff2, image/webp)crossorigin: Required for fonts and CORS requests<link
rel="preload"
href="font.woff2"
as="font"
type="font/woff2"
crossorigin
>Prefetch - Future Resources
What is Prefetch?
Prefetch tells browser: "Load this when idle, I'll need it later"
<link rel="prefetch" href="/next-page.js">
<link rel="prefetch" href="/dashboard-data.json">When to Prefetch
✅ Next page - Likely navigation destination
<link rel="prefetch" href="/dashboard">✅ Future route bundles - Code for next page
<link rel="prefetch" href="/chunks/dashboard.js">✅ API data - Fetch data user will likely need
<link rel="prefetch" href="/api/user/profile">Dynamic Prefetching
// Prefetch on hover
function PrefetchLink({ href, children }) {
const handleMouseEnter = () => {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = href;
document.head.appendChild(link);
};
return (
<a href={href} onMouseEnter={handleMouseEnter}>
{children}
</a>
);
}React Implementation
import Head from 'next/head';
function Page() {
return (
<>
<Head>
{/* Prefetch next likely page */}
<link rel="prefetch" href="/dashboard.js" />
</Head>
<a href="/dashboard">Go to Dashboard</a>
</>
);
}Preconnect & DNS-Prefetch
Preconnect
Establish early connection to external domains.
<!-- Connect to API domain -->
<link rel="preconnect" href="https://api.example.com">
<!-- Connect to CDN -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- Google Fonts (need both) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>DNS-Prefetch
Resolve DNS early (lighter than preconnect).
<!-- Just DNS lookup, no connection -->
<link rel="dns-prefetch" href="https://analytics.com">When to Use Each
<!-- High priority: preconnect -->
<link rel="preconnect" href="https://api.example.com">
<!-- Lower priority: dns-prefetch -->
<link rel="dns-prefetch" href="https://analytics.com">Preconnect = DNS + TCP + TLS (full connection)
DNS-Prefetch = DNS only (faster but less complete)
Best Practices
What to Preload
✅ Do Preload:
❌ Don't Preload:
Preload Example
<head>
<!-- Preload only critical resources -->
<link rel="preload" href="/fonts/inter-bold.woff2" as="font" crossorigin>
<link rel="preload" href="/hero.webp" as="image">
<!-- Regular resources -->
<link rel="stylesheet" href="/styles.css">
<script defer src="/app.js"></script>
</head>What to Prefetch
✅ Do Prefetch:
❌ Don't Prefetch:
Common Mistakes
<!-- ❌ Bad: Preload everything -->
<link rel="preload" href="image1.jpg" as="image">
<link rel="preload" href="image2.jpg" as="image">
<link rel="preload" href="image3.jpg" as="image">
<!-- Too many, slows down critical resources -->
<!-- ✅ Good: Preload only critical -->
<link rel="preload" href="hero.jpg" as="image">
<!-- ❌ Bad: Missing 'as' attribute -->
<link rel="preload" href="style.css">
<!-- ✅ Good: Include 'as' attribute -->
<link rel="preload" href="style.css" as="style">
<!-- ❌ Bad: Preload but never use -->
<link rel="preload" href="unused.js" as="script">
<!-- Browser warning: preload not used -->
<!-- ✅ Good: Preload and use -->
<link rel="preload" href="app.js" as="script">
<script src="app.js"></script>