Tags: pwa, service-worker, cache-api, web-manifest, indexeddb, offline, workbox
Level: intermediate
TL;DR: Progressive Web Apps combine web reach with native app capabilities using Service Workers, Web App Manifests, and aggressive caching.
Service Workers act as programmable client-side network proxies running in background threads.
Web App Manifest is a JSON file defining app metadata, display modes, and icons for installation.
Cache Storage API provides programmatic caching for network requests and responses.
Service Worker lifecycle consists of registering, installing, activating, and fetching phases.
IndexedDB stores structured client-side data for complete offline capability.
Caching strategies determine how requests route between network and cache.
Background Sync API defers network requests until stable connectivity resumes.
Push API and Notification API enable background push notifications even when closed.
Web capabilities provide hardware access like file system, Bluetooth, and contacts.
Q: How does a Service Worker differ from a Web Worker?R: I explain that both run off the main thread, but a Service Worker acts as a network proxy intercepting HTTP requests and controlling caching, whereas Web Workers handle CPU-intensive computations without request interception capabilities.
Q: What are the most common caching strategies and when do you use them?R: I use Cache-First for hashed static assets, Network-First for real-time dynamic data, and Stale-While-Revalidate for non-critical assets like avatars where immediate rendering and background updating work best.
Q: How do you handle Service Worker updates safely without breaking active client sessions?R: I avoid calling self.skipWaiting() automatically to prevent version mismatch across open tabs. Instead, I notify users with an "Update available" prompt that triggers activation and page reload upon user confirmation.
Q: Why does a Service Worker require HTTPS?R: Because it intercepts network traffic and can manipulate HTTP responses, making an unencrypted Service Worker vulnerable to man-in-the-middle attacks.
Caching sw.js via HTTP cache headers prevents clients from receiving Service Worker updates.
Calling skipWaiting() blindly can crash active tabs running mismatched asset versions.
Forgetting that Service Workers run in a worker context without access to DOM or window.
Failing to clean up outdated caches during the activate event, exhausting browser quota.
Storing unbounded dynamic API responses in Cache Storage without size eviction policies.
Assuming background sync works across all iOS Safari versions due to partial WebKit support.
// Service Worker Registration
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
try {
const registration = await navigator.serviceWorker.register('/sw.js', { scope: '/' });
registration.addEventListener('updatefound', () => {
const newWorker = registration.installing;
newWorker?.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
console.log('New update available');
}
});
});
} catch (error) {
console.error('Service Worker registration failed:', error);
}
});
}
TypeScript
// sw.js: Stale-While-Revalidate Caching Strategy
const CACHE_NAME = 'app-cache-v1';
self.addEventListener('fetch', (event: FetchEvent) => {
event.respondWith(
caches.open(CACHE_NAME).then(async (cache) => {
const cachedResponse = await cache.match(event.request);
const networkFetch = fetch(event.request).then((networkResponse) => {
if (networkResponse.ok) {
cache.put(event.request, networkResponse.clone());
}
return networkResponse;
});
return cachedResponse || networkFetch;
})
);
});
JSON
// manifest.json
{
"name": "Progressive Web App",
"short_name": "PWA",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0f172a",
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
[ ] Storage quota estimation and eviction policies via navigator.storage.estimate()
[ ] iOS Safari limitations on background sync and web push notifications
[ ] Workbox window integration and Precaching strategies
[ ] Periodic Background Sync API lifecycle and browser permission requirements
[ ] Navigation preload optimization for Service Worker start-up latency
MDN Web Docs: Progressive Web Apps
W3C Service Workers Specification
Google Chrome Developers: Workbox Documentation
web.dev: Learn PWA