Service Workers Basics
Use a secure server
Service Workers require using the https protocol. To create a key and certificate you can follow the instructions in the yesterdays story: 21 Key and certificate for https on localhost.
Then add these to your server and enable using https. For simple experiments you can use the `liveserver` but the demo here at github.io also works and you can at least follow the implementation.
Register
Service Workers are ^bound to a given domain (and path) and are not bound to a web page. They will continue executing even after navigating away from the domain.
Starting a Service Worker is done by registering a URL for a javascript file:
await navigator.serviceWorker.register('worker.js');
The script will be loaded and executed async and the events will happen.
By using the navigator.serviceWorker
object some methors are available to control the service in the background.
Implementing a Service Worker
In the javascript file you will setup the worker and listen to events. The following events are the most important:
install -- This event can be used for pre-loading or cleanup of the cache.
activate -- When the service worker is activated.
You should call self.clients.claim();
to enable all actually running pages (including the current) page to use the service worker.
fetch -- This event will be used to inform about that the current page executes a fetch(). Here caching can be implemented.
Here is a basic Service Worker for strong caching of several files but not services:
// Service Worker implementation for caching static data
// of type *.htm, *.js', *.css', *.ico'
// bot not *.json or other services
const cacheName = 'pwa-v2';
const cacheFileTypes = new Set([
'htm', 'js', 'css', 'ico', 'pdf'
]);
const cachePreloadFiles = [
'advent2022.css',
'advent2022.js'
];
self.addEventListener('install', (evt) => {
console.log('sw:install...');
evt.waitUntil(
caches.open(cacheName)
.then(cache => {
console.log('sw:delete...');
cache.delete('/favicon.ico');
return (cache);
})
.then(cache => {
console.log('sw:add...');
return (cache.addAll(cachePreloadFiles));
})
);
});
self.addEventListener('activate', (_evt) => {
console.log('sw:activated.');
self.clients.claim();
});
// Try for a cached ressource and add response to the Cache.
async function tryAddCache(req) {
console.log('try:', req.url);
let response = await caches.match(req);
if (response) {
console.log('sw:fromCache', req.url);
} else {
console.log('sw:fetch', req.url);
response = await fetch(req);
const cl = response.clone();
caches.open(cacheName)
.then(cache => {
console.log('sw:toCache', req.url);
cache.put(req, cl);
});
}
return response;
};
self.addEventListener('fetch', (evt) => {
const req = evt.request;
const url = new URL(evt.request.url);
const path = url.pathname;
console.log('sw:request', req.mode, path);
const pos = path.lastIndexOf('.');
// caching allowed ?
if ((pos >= 0) && (cacheFileTypes.has(path.substring(pos + 1).toLowerCase()))) {
const res = tryAddCache(req);
console.log('sw:response', res);
evt.respondWith(res);
} else {
// default fetch procedure...
}
});
// End.
Implementation hints
This is only one step towards pwa applications but an important one.
To see registerend and running Service Workers in your browser open the url
edge://serviceworker-internals/
(or similar).
This list has some useful functionality to stop and unregister service workers.
You may need while development.
Do not enable caching while you implement. It my hurt.
In edge://serviceworker-internals/
you can find the "inspect" button
that can be used to start a debugger for a specific Service Worker
and see the console output.
See Also
- 20 Web Workers Basics
- 21 create Key and certificate for https on localhost
- https://serviceworke.rs/
- https://w3c.github.io/ServiceWorker
- https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker
- https://developer.mozilla.org/en-US/docs/Web/API/Cache
- https://riptutorial.com/javascript/example/11067/a-simple-service-worker
- https://developer.chrome.com/docs/workbox/
- https://developer.chrome.com/docs/workbox/caching-strategies-overview/
- https://github.com/mdn/dom-examples/tree/main/service-worker/simple-service-worker