Resource Hints: Preload & Prefetch for Faster Loading
Resource hints optimize loading by telling browsers what to fetch early. Use strategically for maximum impact.
Quick Navigation: Preload - Critical Resources • Prefetch - Future Resources • Preconnect & DNS-Prefetch • Best Practices
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: Only preload 2-3 critical resources. Preloading too much defeats the purpose.
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>