11. Service Worker with Freshness-First Navigation Strategy

Status

Superseded — 2026-04-24

Superseded by ADR 0016.

Context

The blog publishes on a Monday/Thursday cadence. Readers returning a few days later should see new posts without having to hard-refresh. Angular’s service worker supports two navigation strategies: performance (serve from cache immediately, check for updates in the background) and freshness (attempt network first, fall back to cache when offline). The default is performance, which is the right call for apps that ship rarely and want aggressive offline behavior; it is the wrong call for a publishing site, where a reader hitting a stale cached shell can miss a deploy for hours.

Decision

The service worker uses "navigationRequestStrategy": "freshness". Asset caching is segmented by resource type.

  • ngsw-config.json sets navigationRequestStrategy: "freshness". Navigation requests attempt the network first and fall back to cache only on failure.
  • The app asset group (favicon.svg, *.css, *.js) uses installMode: "prefetch" — the application shell is cached on install so the site works offline and loads fast on repeat visits.
  • The assets asset group (images, fonts) uses installMode: "lazy" with updateMode: "prefetch" — assets are cached on first use, and once cached, updates are pulled eagerly on the next version.
  • The worker registers with registrationStrategy: 'registerWhenStable:30000' and is disabled entirely in dev mode (enabled: !isDevMode()).

Consequences

  • A reader opening the site sees fresh HTML when online. A new deploy propagates on the next navigation, not after a second visit or a hard refresh.
  • Offline readers still get a working site. The app shell and any previously viewed assets remain cached and usable.
  • Every navigation pays a network round-trip before rendering. On slow connections this trades some perceived speed for content currency. For a publishing site, that is the correct trade.
  • The dual-theme Shiki and Mermaid outputs produced by the build pipeline inflate asset bytes, but lazy caching means readers only pay for what they actually view.
  • Switching to performance later would reverse the trade-off: faster repeat navigation, slower propagation of new content. Worth reconsidering only if publish cadence slows significantly.
  • Service worker caching interacts with deploy workflows. A broken worker registration in production could strand readers on a stale version; the registerWhenStable:30000 delay and the dev-mode disable limit but do not eliminate that risk.