Add Service Worker Caching

Pick caching strategies by resource behavior, not by tutorial habit.

Strategy Table

ResourceStrategyWhy
Versioned JS/CSS/fontsCache first or precacheFingerprinted assets are immutable
App shell HTMLNetwork first with offline fallbackAvoid serving old shell forever
Static imagesCache first with expirationSaves bandwidth; stale images are usually acceptable
Reference dataStale while revalidateFast UI plus background freshness
User-specific API dataNetwork first with short timeoutAvoid stale account/business state
MutationsNetwork only plus explicit outboxDo not hide failed writes in response caches

Handwritten Runtime Cache

self.addEventListener('fetch', (event) => {
  const url = new URL(event.request.url);

  if (url.pathname.startsWith('/assets/')) {
    event.respondWith(cacheFirst(event.request, 'assets-v1'));
  }
});

async function cacheFirst(request, cacheName) {
  const cache = await caches.open(cacheName);
  const cached = await cache.match(request);
  if (cached) return cached;

  const response = await fetch(request);
  cache.put(request, response.clone());
  return response;
}

Rules

  • Version cache names.
  • Delete old caches during activate.
  • Add expiration for unbounded runtime caches.
  • Do not cache opaque third-party responses without understanding quota impact.
  • Keep authenticated caches user-safe.