Resource loading strategies - preload, prefetch, modulepreload
Resource Loading Strategies are techniques for optimizing resource loading in browsers. Proper use of preload, prefetch, and other hints can significantly speed up page loading.
Loading Strategy Spectrum
Critical Path
Preload Needed now
Prefetch Needed soon
Prerender Next page
Preload โ Load this immediately!
Purpose: Load critical resources as early as possible.
Preload Syntax
<!-- Critical fonts -->
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<!-- Critical CSS -->
<link rel="preload" href="/critical.css" as="style">
<!-- Hero image -->
<link rel="preload" href="/hero.jpg" as="image">
<!-- JavaScript module -->
<link rel="preload" href="/app.js" as="script">When to Use Preload
Good:
<!-- Fonts used in critical CSS -->
<link rel="preload" href="/fonts/heading.woff2" as="font" crossorigin>
<!-- LCP image (Largest Contentful Paint) -->
<link rel="preload" href="/hero-image.jpg" as="image">
<!-- Critical CSS (above the fold) -->
<link rel="preload" href="/above-fold.css" as="style">Bad:
<!-- Don't 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">
<!-- This slows down loading! -->Resource Types (as attribute)
| Type | Example |
|---|---|
script | JavaScript files |
style | CSS files |
font | Fonts (requires crossorigin) |
image | Images |
fetch | API requests, JSON |
video | Video files |
audio | Audio files |
Prefetch โ Load when idle
Purpose: Load resources for next navigation (low priority).
Prefetch Syntax
<!-- Page user will likely navigate to -->
<link rel="prefetch" href="/next-page.html">
<!-- JavaScript for next page -->
<link rel="prefetch" href="/next-page.js">
<!-- Images that will appear on scroll -->
<link rel="prefetch" href="/below-fold-image.jpg">When to Use Prefetch
Good:
<!-- On product page - prefetch cart -->
<link rel="prefetch" href="/cart.js">
<!-- On landing page - prefetch signup page -->
<link rel="prefetch" href="/signup">
<!-- In carousel - prefetch next image -->
<link rel="prefetch" href="/carousel-image-2.jpg">Bad:
<!-- Don't prefetch critical resources for current page! -->
<link rel="prefetch" href="/hero-image.jpg"> <!-- Should be preload! -->Modulepreload โ Preload for ES modules
Purpose: Preload for JavaScript modules + their dependencies.
Modulepreload Syntax
<!-- Load module and its dependencies -->
<link rel="modulepreload" href="/app.js">
<!-- This will also load imports inside app.js: -->
<!-- import { utils } from './utils.js' -->
<!-- import { api } from './api.js' -->Modulepreload Benefits
// app.js
import { helper } from './helper.js';
import { api } from './api.js';
// Without modulepreload:
// 1. Load app.js
// 2. Parse app.js
// 3. Discover imports
// 4. Load helper.js and api.js Delay!
// With modulepreload:
// 1. Load app.js, helper.js, api.js in parallel
// 2. Parse and executeDNS-Prefetch โ Resolve DNS early
Purpose: Perform DNS lookup for external domain.
DNS-Prefetch Syntax
<!-- External resources -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="dns-prefetch" href="https://analytics.google.com">Time Savings
Without dns-prefetch:
User action โ DNS lookup (20-120ms) โ Connect โ Request
With dns-prefetch:
DNS already ready! โ Connect โ Request
Savings: 20-120msPreconnect โ Establish connection early
Purpose: DNS + TCP + TLS handshake for external domain.
Preconnect Syntax
<!-- Critical external resources -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com">What preconnect includes
1. DNS lookup (20-120ms)
2. TCP handshake (RTT)
3. TLS handshake (RTT)
----------------------------
Total savings: 100-500ms!Preconnect vs DNS-Prefetch
| dns-prefetch | preconnect | |
|---|---|---|
| DNS lookup | Yes | Yes |
| TCP handshake | No | Yes |
| TLS handshake | No | Yes |
| Cost | Cheap | More expensive |
| When | Many domains | Critical domains (2-3) |
Priority Hints
Attribute fetchpriority controls loading priority:
<!-- High priority for LCP image -->
<img src="/hero.jpg" fetchpriority="high">
<!-- Low priority for below-fold image -->
<img src="/footer-logo.jpg" fetchpriority="low" loading="lazy">
<!-- Critical CSS -->
<link rel="stylesheet" href="/critical.css" fetchpriority="high">
<!-- Non-critical JavaScript -->
<script src="/analytics.js" fetchpriority="low" async></script>Browser Priorities (default)
| Resource | Priority |
|---|---|
| HTML | Highest |
CSS (in <head>) | Highest |
| Fonts | High |
Scripts (in <head>) | High |
| Images (in viewport) | High |
| Scripts (async) | Low |
| Images (below fold) | Low |
Critical Request Chains
Critical request chain โ sequence of blocking resources:
<!-- Bad: deep chain -->
<html>
<head>
<link rel="stylesheet" href="/style.css">
<!-- In style.css: -->
<!-- @import url('/fonts.css'); -->
<!-- In fonts.css: -->
<!-- @font-face { src: url('/font.woff2'); } -->
</head>Depth = 3:
- Load style.css
- Parse โ find fonts.css โ load
- Parse โ find font.woff2 โ load
Solution:
<!-- Good: parallel loading -->
<head>
<link rel="preload" href="/font.woff2" as="font" crossorigin>
<link rel="stylesheet" href="/style.css">
</head>
<!-- Depth = 1, everything parallel! -->Practical Examples
E-commerce Site
<head>
<!-- Critical for LCP -->
<link rel="preload" href="/hero-product.jpg" as="image" fetchpriority="high">
<link rel="preload" href="/fonts/main.woff2" as="font" crossorigin>
<!-- Critical external resources -->
<link rel="preconnect" href="https://cdn.shopify.com">
<!-- Non-critical external -->
<link rel="dns-prefetch" href="https://analytics.google.com">
<!-- Prefetch for likely navigation -->
<link rel="prefetch" href="/cart">
<link rel="prefetch" href="/checkout.js">
</head>SPA (Single Page Application)
<!-- Preload critical chunks -->
<link rel="modulepreload" href="/app.js">
<link rel="modulepreload" href="/router.js">
<!-- Prefetch route chunks -->
<link rel="prefetch" href="/routes/home.js">
<link rel="prefetch" href="/routes/about.js">Best Practices
Preload only critical resources
Maximum 3-5 preloads. More = bandwidth competition.
Prefetch for predictable navigation
Analyze user journey and prefetch likely transitions.
Preconnect to critical CDNs
No more than 2-3 preconnects (expensive operation)
Use fetchpriority
Help browser prioritize LCP resources.
Measure impact
Use Lighthouse, WebPageTest for validation.
Analysis Tools
Chrome DevTools
Network tab โ Priority column
High = Critical Path
Low = Prefetch candidatesLighthouse
- "Preload key requests"
- "Reduce initial server response time"
- "Eliminate render-blocking resources"Summary:
Proper use of resource hints (preload, prefetch, preconnect) can reduce load time by 20-50%. Key is understanding Critical Path and user journey. Preload for critical resources, prefetch for likely transitions, preconnect for external APIs/CDNs.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.