Use the Application tool to manage storage for web app pages
- it's like being a digital hoarder, but organized!
We've got:
They act as proxy servers between web applications, the browser, and the network. They primarily enable offline experiences, caching, push notifications, and background sync. Service workers intercept network requests, allowing control over how the application behaves in various situations, especially when the network is unavailable. They operate in a separate thread, without DOM access, and are designed to be fully asynchronous.
They are general-purpose background threads designed to run CPU-intensive tasks without blocking the main thread, ensuring a responsive user interface. Background workers facilitate parallel processing, allowing complex computations or data processing to occur independently. They do not intercept network requests; instead, the main thread explicitly sends messages to them. Their lifespan is tied to the tab or page they are created in, terminating when the tab is closed.
| Feature | Service Worker | Background Worker (Web Worker) |
|---|---|---|
| Purpose | Network proxy, offline support, caching, push notifications | Background processing, offloading CPU-intensive tasks |
| Network | Intercepts network requests | Does not intercept network requests |
| DOM Access | No DOM access | No DOM access |
| Lifespan | Independent of the page/tab | Tied to the page/tab |
| Use Cases | PWAs, offline functionality, push notifications | Complex calculations, data processing, real-time applications |
| Communication | Intercepts fetch requests, listens for push events | Receives messages via postMessage |
// In your main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => console.log('SW registered'))
.catch(error => console.log('SW registration failed'));
}
// In sw.js
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/',
'/styles.css',
'/app.js'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
install event fire?The install event fires immediately after the service worker is successfully downloaded and parsed by the browser, triggered by the navigator.serviceWorker.register('/sw.js') call.
The sequence is:
register() is called → browser downloads sw.jsinstall event firesevent.waitUntil() keeps the SW in the "installing" phase until all cache.addAll() promises resolveaddAll 404s) → installation fails, SW is discardedKey points:
install fires right after registration, then the SW activates (since there's no previous version).install fires again only if sw.js has changed (even a single byte difference). The new SW then waits until all tabs using the old SW are closed before activating.install does NOT fire if the browser's byte-compared cache of sw.js matches the fetched version — the existing SW is reused as-is.fetch event fire?The fetch event fires on every network request made by pages the service worker controls — but with an important caveat:
Not immediately on first visit. Even though the SW installs and activates on the first visit, it does not control the page that registered it. The page must be navigated to again (refresh or revisit) for the SW to intercept its requests.
The timeline is:
fetch does NOT fire. All requests go straight to the network.fetch fires for every request: the HTML page itself, CSS, JS, images, fonts, API calls — everything.For each intercepted request, the code:
fetch() from the networkExceptions — the fetch event does not fire for:
sw.js)
// In your main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: 'Start calculation' });
worker.onmessage = function(e) {
console.log('Result:', e.data);
};
// In worker.js
self.onmessage = function(e) {
// Heavy computation here
const result = e.data.data + ' completed';
self.postMessage(result);
};
While both operate in background threads, their roles are distinct. Service workers enhance web application capabilities related to network requests and offline access, whereas background workers improve performance by handling computationally intensive tasks separately from the main thread.