Service Worker Caching Strategies Explained
Caching strategies are the core functionality of Service Worker, determining how to handle network requests and cache resources.
1. Cache First
Description: Prioritize cache retrieval, fall back to network if cache doesn't exist.
Use Cases: Static resources (CSS, JS, images), infrequently changing content.
javascriptself.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(response => { return response || fetch(event.request); }) ); });
Pros: Fast loading, offline available Cons: May return stale content
2. Network First
Description: Prioritize network request, fall back to cache on failure.
Use Cases: Real-time data requirements (API requests, user data).
javascriptself.addEventListener('fetch', event => { event.respondWith( fetch(event.request).catch(() => { return caches.match(event.request); }) ); });
Pros: Gets latest data Cons: Poor experience when network is slow
3. Cache Only
Description: Only retrieve from cache, no network requests.
Use Cases: Precached static resources.
javascriptself.addEventListener('fetch', event => { event.respondWith(caches.match(event.request)); });
4. Network Only
Description: Only make network requests, no cache usage.
Use Cases: Highly time-sensitive data (payments, sensitive operations).
javascriptself.addEventListener('fetch', event => { event.respondWith(fetch(event.request)); });
5. Stale While Revalidate
Description: Return cache first, update cache in background.
Use Cases: Content needing fast response while staying updated.
javascriptself.addEventListener('fetch', event => { event.respondWith( caches.open('dynamic-cache').then(cache => { return cache.match(event.request).then(response => { const fetchPromise = fetch(event.request).then(networkResponse => { cache.put(event.request, networkResponse.clone()); return networkResponse; }); return response || fetchPromise; }); }) ); });
Pros: Fast response + background update Cons: Users may see old data
6. Custom Strategy Combination
Choose different strategies based on request type:
javascriptself.addEventListener('fetch', event => { const { request } = event; const url = new URL(request.url); // Static resources - Cache First if (request.destination === 'style' || request.destination === 'script' || request.destination === 'image') { event.respondWith(cacheFirst(request)); } // API requests - Network First else if (url.pathname.startsWith('/api/')) { event.respondWith(networkFirst(request)); } // Page navigation - Stale While Revalidate else if (request.mode === 'navigate') { event.respondWith(staleWhileRevalidate(request)); } });
Caching Strategies Comparison
| Strategy | Speed | Real-time | Offline | Use Cases |
|---|---|---|---|---|
| Cache First | ⭐⭐⭐ | ⭐ | ✅ | Static resources |
| Network First | ⭐ | ⭐⭐⭐ | ✅ | Real-time data |
| Stale While Revalidate | ⭐⭐⭐ | ⭐⭐ | ✅ | Balanced scenarios |
| Cache Only | ⭐⭐⭐ | ⭐ | ✅ | Precached resources |
| Network Only | ⭐ | ⭐⭐⭐ | ❌ | Sensitive operations |
Best Practices
- Layered Caching: Cache First for static, Network First for APIs
- Cache Version Control: Use version numbers for cache management
- Cache Size Limits: Regularly clean expired caches
- Error Handling: Provide graceful degradation when network fails