Skip to main content
Practice Problems

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

html
<!-- 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:

html
<!-- 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:

html
<!-- 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)

TypeExample
scriptJavaScript files
styleCSS files
fontFonts (requires crossorigin)
imageImages
fetchAPI requests, JSON
videoVideo files
audioAudio files

Prefetch โ€” Load when idle

Purpose: Load resources for next navigation (low priority).

Prefetch Syntax

html
<!-- 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:

html
<!-- 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:

html
<!-- 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

html
<!-- 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

javascript
// 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

DNS-Prefetch โ€” Resolve DNS early

Purpose: Perform DNS lookup for external domain.

DNS-Prefetch Syntax

html
<!-- 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-120ms

Preconnect โ€” Establish connection early

Purpose: DNS + TCP + TLS handshake for external domain.

Preconnect Syntax

html
<!-- 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-prefetchpreconnect
DNS lookupYesYes
TCP handshakeNoYes
TLS handshakeNoYes
CostCheapMore expensive
WhenMany domainsCritical domains (2-3)

Priority Hints

Attribute fetchpriority controls loading priority:

html
<!-- 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)

ResourcePriority
HTMLHighest
CSS (in <head>)Highest
FontsHigh
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:

html
<!-- 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:

  1. Load style.css
  2. Parse โ†’ find fonts.css โ†’ load
  3. Parse โ†’ find font.woff2 โ†’ load

Solution:

html
<!-- 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

html
<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)

html
<!-- 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 candidates

Lighthouse

- "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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems