Service Worker Essentials¶
Service workers are the backbone of Progressive Web App (PWA) functionality, enabling features like offline access, background synchronization, and URL interception. By acting as a programmable network proxy, they mediate between the client and the network, allowing developers to control how resources are fetched, cached, and served. This section dives into their role in three critical areas: offline functionality, background sync, and URL interception.
Offline Functionality: Caching and Fallback Strategies¶
Service workers enable offline access by intercepting network requests and serving cached resources when the network is unavailable. This is achieved through the Cache API, which allows developers to store and retrieve assets locally.
Key Concepts¶
- Cache Storage: Assets like HTML, CSS, JS, and images are cached during the service worker's
installlifecycle phase. - Network Fallback: If a resource isn't cached, the service worker can fetch it from the network or provide a fallback (e.g., a placeholder or error message).
- Cache Versioning: Use versioned cache names to manage updates and avoid stale content.
Example: Caching Assets on Install¶
// sw.js
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1-cache').then((cache) => {
return cache.addAll([
'/',
'/index.html',
'/styles.css',
'/app.js',
]);
})
);
});
Example: Serving Cached Content¶
// sw.js
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
Background Sync: Deferring Network Requests¶
Service workers can queue network requests to execute when the device regains connectivity using the Background Sync API. This is ideal for tasks like form submissions or data sync.
Key Concepts¶
- Sync Events: The service worker listens for
syncevents triggered by the browser when the device is online. - Task Scheduling: Use
SyncManagerto schedule tasks that persist across sessions. - User Consent: Sync tasks require user interaction (e.g., a button click) to initiate.
Example: Scheduling a Sync Task¶
// main.js
navigator.serviceWorker.register('sw.js').then((registration) => {
registration.sync.register('sync-task');
});
Example: Handling a Sync Task¶
// sw.js
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-task') {
event.waitUntil(fetch('/api/submit-data').catch(() => {}));
}
});
URL Interception: Controlling Network Requests¶
Service workers can intercept and handle network requests using the fetch event. This allows for custom routing, caching strategies, and even dynamic content generation.
Key Concepts¶
- Request Matching: Use
matchorrespondWithto control how requests are handled. - Navigation Interception: Intercept navigation requests to serve cached pages or redirect users.
- API Requests: Handle API calls to add data to the cache or modify responses.
Example: Intercepting Navigation Requests¶
// sw.js
self.addEventListener('fetch', (event) => {
if (event.request.mode === 'navigate') {
event.respondWith(
caches.match('/').then((response) => {
return response || fetch(event.request);
})
);
}
});
Example: Intercepting API Requests¶
// sw.js
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
event.respondWith(
fetch(event.request).then((response) => {
// Cache the response for future use
return caches.open('v1-cache').then((cache) => {
cache.put(event.request, response.clone());
return response;
});
})
);
}
});
Diagram: Service Worker Workflow¶
Key Takeaways¶
- Service workers enable offline access by caching assets and serving them when the network is unavailable.
- Background sync allows deferred network requests to execute when the device is online, ensuring data consistency.
- URL interception gives fine-grained control over how requests are handled, enabling custom caching and routing strategies.
- Proper registration, cache management, and event handling are critical for reliable PWA functionality.