A service worker sits between your application and the network, and answers when the network cannot. Everything depends on which responses it is allowed to keep.
The four strategies
- Cache first. Serve from cache, go to the network only on a miss. For fonts, icons and compiled assets, which change only when you deploy.
- Network first. Try the network, fall back to cache. For content pages, where a slightly stale page beats an error page.
- Stale while revalidate. Serve the cached copy immediately, then fetch a fresh one in the background for next time. The fastest of the four, and the one whose trade-off is easiest to miss.
- Network only. Never cache. For everything below.
A word on stale while revalidate
It feels instant because it never waits for the network. That is also its catch: the visitor always sees the previous version. Publish a correction and the first person to arrive still reads the mistake; they get the fix on their second visit, which they may never make.
It suits things where being one visit behind costs nothing: an avatar, a list of tags, a sidebar of recent items. It does not suit anything a reader might act on, and it is a poor fit for a page you will need to correct in a hurry.
If you use it, give yourself a way out: a versioned cache name you can bump on deployment turns « one visit behind » into « behind until the next release », which is at least a boundary you control.
What belongs in « never »
- Anything with a price, a stock level or an availability.
- Anything reflecting a permission. A page cached while an administrator was logged in, served later to somebody else, is a data leak with no attacker involved.
- Anything with a personal name in it. Same reason.
- Every non-idempotent request. POST, PUT, DELETE. Replaying one is not caching, it is acting twice.
- Authentication responses. A cached login page with a stale token is a support ticket that takes three days to reproduce.
Version your cache, and clean up
Put a version in the cache name and delete the old ones on activate. Without that, every deployment leaves a full copy behind, and a user who visits once a month carries a year of dead assets.
Test the failure you will actually have
Switching the browser to offline is the easy case: requests fail immediately and your fallbacks fire. The interesting case is the slow, flaky connection where requests hang rather than fail, and a cache-first strategy quietly serves month-old data while the spinner turns.
Throttle rather than disconnect. That is where the bugs are.