Service Worker Lifecycle Events: Install and Activate
Service workers act as proxy servers that sit between web
applications, the browser, and the network, enabling offline
capabilities, background sync, and push notifications. This article
explains the service worker lifecycle, focusing specifically on how the
install and activate events function in
JavaScript to manage asset caching, application updates, and resource
cleanup.
The Service Worker Lifecycle
A service worker operates independently of the main browser thread and follows a strict lifecycle designed to prevent conflicts between different versions of your application. The primary phases of this lifecycle are:
- Registration: The browser downloads and registers the service worker script.
- Installation: The browser attempts to install the worker, preparing it for execution.
- Activation: The worker takes control of clients and clears outdated resources.
- Redundancy/Termination: The worker becomes idle,
handles functional events like
fetch, or is terminated when no longer needed.
The install Event
The install event is the first event a service worker
receives. It fires only once per service worker version. If the script
contains even a single-byte change compared to the currently running
version, the browser treats it as a new worker and triggers a new
install event.
Purpose of install
The primary role of the install event is to prepare the
service worker for use, typically by pre-caching static assets (such as
HTML, CSS, JavaScript, and key images) required to run the application
offline.
Code Implementation
const CACHE_NAME = 'app-cache-v1';
const ASSETS_TO_CACHE = [
'/',
'/index.html',
'/styles.css',
'/app.js'
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
return cache.addAll(ASSETS_TO_CACHE);
})
);
});Key Mechanisms:
event.waitUntil(): This method takes a Promise and uses it to know how long installation takes, and whether it succeeded. If the promise rejects (for example, if a file fails to fetch), the browser discards the service worker, and it will not proceed to the activation phase.self.skipWaiting(): By default, an updated service worker waits until all open tabs using the previous version are closed before activating. Callingself.skipWaiting()forces the new worker to bypass the “waiting” state and activate immediately.
The activate Event
Once a service worker installs successfully and no older service
workers are controlling existing clients, the activate
event fires.
Purpose of activate
The activate event is used primarily for cleanup tasks,
such as removing outdated caches created by previous service worker
versions. Performing cleanup during install risks breaking
currently open tabs relying on the old cache; thus, cleanup is deferred
to activate.
Code Implementation
self.addEventListener('activate', (event) => {
const cacheWhitelist = ['app-cache-v2'];
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});Key Mechanisms:
- Cache Management: Iterating over
caches.keys()and deleting any cache keys not present in the current whitelist ensures the user’s storage is not polluted with stale files. clients.claim(): Even after activation, existing open pages will not be controlled by the new worker until they are reloaded. Callingself.clients.claim()inside theactivateevent allows the active service worker to immediately take control of all open clients.
Summary of Differences
| Feature | install Event |
activate Event |
|---|---|---|
| Execution Timing | Immediately after registration/update | After previous workers are stopped/skipped |
| Primary Responsibility | Populating initial caches with critical assets | Purging stale caches and migrating data |
| Failure Handling | Aborts installation if any promise rejects | Fails activation, but does not re-run installation |
| Immediate Control Method | self.skipWaiting() |
self.clients.claim() |