Add Service Worker Caching
Pick caching strategies by resource behavior, not by tutorial habit.
Strategy Table
| Resource | Strategy | Why |
|---|---|---|
| Versioned JS/CSS/fonts | Cache first or precache | Fingerprinted assets are immutable |
| App shell HTML | Network first with offline fallback | Avoid serving old shell forever |
| Static images | Cache first with expiration | Saves bandwidth; stale images are usually acceptable |
| Reference data | Stale while revalidate | Fast UI plus background freshness |
| User-specific API data | Network first with short timeout | Avoid stale account/business state |
| Mutations | Network only plus explicit outbox | Do 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.