Resource Hints: Preload & Prefetch for Faster Loading

Medium

Resource hints optimize loading by telling browsers what to fetch early. Use strategically for maximum impact.

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:

1-2 critical fonts
Hero/LCP image
Critical CSS (if external)
Essential first-paint JS

Don't Preload:

Everything (defeats purpose)
Below-fold resources
Non-critical assets
More than 3-4 resources

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:

Next page JS chunks
Likely navigation targets
Search results
User profile data

Don't Prefetch:

All possible pages
Heavy resources
Rarely accessed content

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>