FSD Frontend System Design

Part III β€” The Speed Β· Lesson 6.8

Service Worker Caching

In one lineA programmable proxy inside the browser β€” you write the cache policy in JavaScript.

Where you've seen itA news app that opens and renders yesterday's headlines on a train with no signal, then quietly updates when the tunnel ends.

  • Time17 min
  • DiagramIntercept flow + the five caching strategies
  • Chapter6 Β· Database & Caching

Diagram

diagram
THE INTERCEPT β€” every request passes through your code

  page ──fetch()──► β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚ Service Worker  β”‚  your JS decides:
                    β”‚   onfetch       β”‚
                    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
                         β”‚       β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       └──────────┐
              β–Ό                             β–Ό
      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚ Cache Storageβ”‚              β”‚   Network    β”‚
      β”‚  (your code) β”‚              β”‚              β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Unlike HTTP caching (6.7), the RULES ARE YOURS β€” per URL,
  per route, per condition.
diagram
FIVE STRATEGIES β€” pick per resource type

  CACHE FIRST          cache ──► (miss) network
    app shell, fonts, hashed assets       fastest, can go stale

  NETWORK FIRST        network ──► (fail) cache
    HTML documents, fresh API data        correct, slower offline path

  STALE-WHILE-REVALIDATE
    serve cache NOW, fetch and update in background
    avatars, feeds, non-critical data     instant + eventually fresh

  NETWORK ONLY         never cache
    payments, auth, analytics             correctness over speed

  CACHE ONLY           precached only
    offline fallback page
diagram
MAPPING A REAL APP

  /                     network-first  (fresh content, offline fallback)
  /assets/*.js|css      cache-first    (hashed, immutable)
  /fonts/*.woff2        cache-first    (never change)
  /api/feed             SWR            (instant, refreshes behind)
  /api/checkout         network-only   (must never be stale)
  /offline.html         precached      (the fallback)

How it works

  1. Precache the shell at install: the HTML fallback, CSS, JS, fonts, and logo.
  2. Route requests by type inside fetch, applying the strategy that matches the resource's freshness needs.
  3. Version your caches (static-v4) and delete old ones in activate, or storage grows without bound.
  4. Cap runtime caches β€” max entries and max age β€” because unbounded image caching will fill the quota.
  5. Use Workbox in production; hand-rolled service workers are where subtle staleness bugs live. Lifecycle details are covered in 9.1.
js
self.addEventListener('fetch', (event) => {
  const { request } = event;
  if (request.mode === 'navigate') {
    event.respondWith(
      fetch(request).catch(() => caches.match('/offline.html'))  // network-first
    );
  } else if (request.url.includes('/assets/')) {
    event.respondWith(
      caches.match(request).then((hit) => hit ?? fetch(request)) // cache-first
    );
  }
});

Trade-offs

Service worker cacheHTTP cache
You write the logicBrowser applies headers
Works fully offlineNeeds the network for revalidation
Per-route strategiesPer-response headers
A bug ships to every user's deviceHeader change takes effect immediately

The danger: a broken service worker is sticky β€” it can keep serving a broken app until it's updated. Always ship a kill switch (an SW that unregisters itself) and test the update path, not just the install path.

Interview angle

"How would you make a news site work offline?"

  • Precache the shell, network-first for documents with an offline fallback, cache-first for hashed assets.
  • Stale-while-revalidate for the feed so it opens instantly and refreshes behind the user.
  • Version the caches, cap the image cache, and keep payments network-only β€” never serve a stale transaction.

Recap

  • The service worker is a proxy you program; HTTP caching is a policy you declare.
  • Match strategy to resource: shell cache-first, documents network-first, feeds SWR.
  • Version and bound your caches, and always have an escape hatch.