Caching Strategies: Overview
Why caching matters
Section titled “Why caching matters”A network request can fail for many reasons — the user is offline, on a slow connection, or the server is temporarily unavailable. Without a cache, any of these conditions means a broken experience. With a well-chosen caching strategy, the browser can serve assets instantly from local storage and sync with the server in the background.
Caching also eliminates unnecessary round trips. A CSS file that has not changed does not need to travel across the network every time someone loads your page. Serving it from a local cache brings load times down from hundreds of milliseconds to near zero.
Precache vs runtime cache
Section titled “Precache vs runtime cache”Precaching happens at service worker install time. You explicitly list the URLs you want cached, and the browser fetches and stores them before the SW activates. This is ideal for your app shell — the HTML, CSS, and JS files that form the structural skeleton of your UI.
Runtime caching happens on demand. The first time a user requests a resource (an image, an API response, a font), the service worker intercepts the fetch, stores the response, and serves subsequent requests from cache. This approach is suitable for dynamic or user-specific content that you cannot enumerate at build time.
Strategy overview
Section titled “Strategy overview”| Strategy | Best for | Trade-off |
|---|---|---|
| Cache-first | Static assets (CSS, JS, images) | Can serve stale assets |
| Network-first | API data, HTML | Slower; needs cache fallback |
| Stale-while-revalidate | Avatars, feeds, config | Eventually consistent |
| Cache-only | Pre-cached app shell | No network fallback |
| Network-only | Payments, analytics | No offline support |
Choosing a strategy
Section titled “Choosing a strategy”flowchart TD
A[Start: incoming request] --> B{Is the asset static?}
B -->|Yes| C[Cache-first]
B -->|No| D{Does freshness matter?}
D -->|Yes, always fresh| E[Network-first]
D -->|Mostly fresh is fine| F[Stale-while-revalidate]
D -->|No network needed| G[Cache-only]
E --> H{Network failed?}
H -->|Yes| I[Serve from cache fallback]
H -->|No| J[Return fresh response and update cache]