DNA🌐 Web BrowserBrowser Networking & Resource Loading
ðŸĶ–DinosaurBrowserPerformanceNetworking

Browser Networking & Resource Loading

HTTP/2, HTTP/3, resource hints, preload, prefetch — the network layer is where performance is won or lost. Architects who control the network control the user experience.

Browser Networking & Resource Loading

Before any JavaScript runs, before any component renders, the browser must fetch resources over the network. The decisions you make about how resources are discovered, prioritized, and delivered determine your app's performance ceiling.

HTTP/1.1 vs HTTP/2 vs HTTP/3

HTTP/1.1 — The Bottleneck

Browser needs: index.html, style.css, app.js, logo.png, font.woff2
 
HTTP/1.1 (one request per connection):
Connection 1: ──[index.html]──[style.css]──[app.js]──
Connection 2: ──[logo.png]──[font.woff2]──
(Browser opens 6 parallel connections max per domain)

Problems:

  • Head-of-line blocking — One slow response blocks everything behind it on that connection
  • Connection limit — Max 6 connections per domain (workaround: domain sharding)
  • Redundant headers — Full headers sent with every request (~500 bytes each)

HTTP/2 — Multiplexing

HTTP/2 (multiple streams on one connection):
Single Connection: ──[html]──[css]──[js]──[img]──[font]──
                   All multiplexed on one TCP connection
                   Each resource is a "stream"

Key features:

  • Multiplexing — Multiple requests/responses on a single connection, interleaved
  • Header compression (HPACK) — Headers compressed, delta-encoded
  • Server push — Server can send resources before the client asks (deprecated in most implementations)
  • Stream priority — Client tells server which resources matter most

HTTP/3 — QUIC Protocol

HTTP/3:
Single QUIC Connection (over UDP):
  Stream 1: [html] ← lost packet? Only stream 1 waits
  Stream 2: [css]  ← keeps flowing
  Stream 3: [js]   ← keeps flowing

Key improvement: Eliminates TCP head-of-line blocking. In HTTP/2, a lost TCP packet stalls ALL streams (because TCP guarantees order). HTTP/3 uses QUIC over UDP — each stream is independent. A lost packet in one stream doesn't affect others.

Additional benefits:

  • 0-RTT connection establishment — Reconnections skip the handshake
  • Connection migration — Survives network changes (WiFi → cellular)
  • Built-in encryption — TLS 1.3 baked into the protocol

When Each Protocol Matters

ScenarioImpact
Many small resources (icons, API calls)HTTP/2 multiplexing eliminates connection limits
High-latency connections (mobile, global users)HTTP/3 0-RTT saves round trips
Lossy networks (mobile, WiFi)HTTP/3 eliminates TCP head-of-line blocking
Large bundlesHTTP/2 stream priority ensures critical CSS/JS loads first

Resource Discovery & Hints

The browser discovers resources in order: HTML → CSS → JS. Resource hints let you tell the browser about resources earlier.

preconnect — Warm Up Connections

<!-- Establish connection before it's needed (DNS + TCP + TLS) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://api.example.com" crossorigin>

Saves 100-500ms per third-party origin. Use for:

  • CDN origins
  • API servers
  • Font providers
  • Analytics endpoints

dns-prefetch — DNS Only

<!-- Lighter than preconnect — just DNS resolution -->
<link rel="dns-prefetch" href="https://analytics.example.com">

Cheaper than preconnect. Use for origins you'll use later (not immediately).

preload — Critical Resources NOW

<!-- Font needed immediately — don't wait for CSS to discover it -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
 
<!-- Hero image needed for LCP -->
<link rel="preload" href="/images/hero.webp" as="image">
 
<!-- Critical JS module -->
<link rel="preload" href="/scripts/critical.js" as="script">

preload says: "This resource is needed for the current page. Start downloading NOW."

as ValueResource Type
scriptJavaScript files
styleCSS files
fontFont files
imageImages
fetchAPI responses

prefetch — Resources for NEXT Page

<!-- User will likely navigate to /dashboard next -->
<link rel="prefetch" href="/dashboard.js" as="script">
<link rel="prefetch" href="/api/dashboard-data" as="fetch">

prefetch says: "This resource will be needed on a future page. Download when idle."

preload vs prefetch

preloadprefetch
PriorityHigh (current page)Low (future navigation)
When usedNeeded within secondsMight be needed eventually
Warning if unusedYes (console warning after 3s)No
Best forFonts, hero images, critical JSNext-page resources

modulepreload — ES Module Preload

<link rel="modulepreload" href="/components/Header.js">

Like preload but also parses and compiles the module immediately, saving time when it's eventually imported.

Resource Loading Priority

The browser assigns priority to resources automatically:

ResourceDefault PriorityNotes
HTMLHighestThe document itself
CSS (in <head>)HighestRender-blocking
Sync <script> (in <head>)HighParser-blocking
Fonts (used above fold)HighNeeded for text rendering
<script defer>Low (during parse)Executed after parsing
Images (above fold)HighVisible to user
Images (below fold)LowNot immediately needed
<script async>LowIndependent script
Prefetch resourcesLowestFuture page resources

fetchpriority — Override Default Priority

<!-- Boost LCP image priority -->
<img src="/hero.webp" fetchpriority="high" alt="Hero">
 
<!-- Lower priority for below-fold images -->
<img src="/footer-logo.webp" fetchpriority="low" alt="Logo" loading="lazy">
 
<!-- Boost critical fetch request -->
<link rel="preload" href="/api/critical-data" as="fetch" fetchpriority="high">

Lazy Loading

Native Lazy Loading

<!-- Browser handles viewport detection automatically -->
<img src="photo.webp" loading="lazy" alt="Photo">
<iframe src="embed.html" loading="lazy"></iframe>

Don't lazy load above-the-fold images — it delays LCP.

Connection-Aware Loading

function getImageQuality() {
  const connection = navigator.connection;
  if (!connection) return 'high';
 
  if (connection.saveData) return 'low';
  if (connection.effectiveType === '4g') return 'high';
  if (connection.effectiveType === '3g') return 'medium';
  return 'low';
}
 
function getImageSrc(baseUrl) {
  const quality = getImageQuality();
  return `${baseUrl}?quality=${quality}`;
}

Image Optimization Strategy

<!-- Modern format with fallback -->
<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="Photo" width="800" height="600">
</picture>
 
<!-- Responsive images -->
<img
  srcset="photo-400.webp 400w,
          photo-800.webp 800w,
          photo-1200.webp 1200w"
  sizes="(max-width: 600px) 400px,
         (max-width: 1000px) 800px,
         1200px"
  src="photo-800.webp"
  alt="Photo"
  width="800"
  height="600"
  loading="lazy"
  decoding="async"
>

Always set width and height — prevents layout shifts (CLS) by reserving space.

Critical Request Chain

The critical request chain is the sequence of dependent requests that must complete before first render:

Without optimization:
HTML → CSS → @import CSS → Font (discovered in CSS) → Render
  1       2            3         4                      total: 4 round trips
 
With optimization:
HTML (inline critical CSS + preload font) → Render
  1                                          total: 1 round trip

Audit with Lighthouse

Lighthouse shows the critical request chain in its report:

  • Which resources block rendering
  • The depth of the chain (number of serial round trips)
  • Total bytes on the critical path

Compression

Original:    app.js (500KB)
Gzip:        app.js.gz (120KB) — 76% reduction
Brotli:      app.js.br (95KB) — 81% reduction

Brotli (br) is 15-25% smaller than Gzip for text assets. All modern browsers support it over HTTPS.

# Nginx configuration
brotli on;
brotli_types text/html text/css application/javascript application/json;

Interview Signal

Senior candidates demonstrate:

  1. Protocol evolution — HTTP/1.1 limitations, HTTP/2 multiplexing, HTTP/3 QUIC advantages
  2. Resource hint fluency — preconnect, preload, prefetch — and when each applies
  3. Priority understanding — Browser's default priorities and how to override them
  4. Critical path thinking — Minimizing the request chain depth for faster first render
  5. Image strategy — Responsive images, modern formats, lazy loading, CLS prevention