Loading...
Loading...
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.
Purpose: Load critical resources as early as possible.
<!-- 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">
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! -->
| Type | Example |
|---|---|
script | JavaScript files |
style | CSS files |
font | Fonts (requires crossorigin) |
image | Images |
fetch | API requests, JSON |
video | Video files |
audio | Audio files |
Purpose: Load resources for next navigation (low priority).
<!-- 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">
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! -->
Purpose: Preload for JavaScript modules + their dependencies.
<!-- 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' -->
// 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 execute
Purpose: Perform DNS lookup for external domain.
<!-- 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">
Without dns-prefetch:
User action → DNS lookup (20-120ms) → Connect → Request
With dns-prefetch:
DNS already ready! → Connect → Request
Savings: 20-120ms
Purpose: DNS + TCP + TLS handshake for external domain.
<!-- Critical external resources -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com">
1. DNS lookup (20-120ms)
2. TCP handshake (RTT)
3. TLS handshake (RTT)
----------------------------
Total savings: 100-500ms!
| 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) |
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>
| 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 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:
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! -->
<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>
<!-- 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">
Maximum 3-5 preloads. More = bandwidth competition.
Analyze user journey and prefetch likely transitions.
No more than 2-3 preconnects (expensive operation).
Help browser prioritize LCP resources.
Use Lighthouse, WebPageTest for validation.
Network tab → Priority column
High = Critical Path
Low = Prefetch candidates
- "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.