Service Workers

service worker

What service workers are and where they are used

We used to get push notifications only on our mobile phones; with the help of service workers we now get them on our computers too! But what are service workers? Put simply, a service worker is a script that runs in the background, and the user does not need to do anything for it to run. Service workers are used for caching files (e.g. CSS), push notifications and geofencing.

The main drawback of service workers, if we can call it a drawback, is that they only work over secure HTTPS connections. That said, while building them we can work in a localhost environment, which makes life much easier.

A tool that will help us further on: if we go to chrome://serviceworker-internals in Chrome, we will see all the service workers on our page.

Service Worker Example

Below is an example of how we first check whether our browser supports service workers, and then register one; if it is not supported, we say so in the console. The service worker lives in the file service-worker.js. With then we simply say what should happen once the service worker has been registered, and with catch we send the error to the console. To clear one thing up: if a user visits our page 10 times, the register function will run each time, but the browser decides whether it actually needs to do anything, depending on whether the service worker has already been registered.


//make sure that Service Workers are supported.
if (navigator.serviceWorker) {
navigator.serviceWorker.register('./service-worker.js', {scope: './about'})
.then(function (registration) {
console.log(registration);
})
.catch(function (e) {
console.error(e);
})
} else {
console.log('Service Worker is not supported in this browser.');
}

Step 2: Creating variables for the files we want to cache

Now that we have told the browser to register the file, we also need to install the service worker and create variables for the files we want to cache, so that later on our website or app does not need an internet connection (by this we mean that the connection may be unreliable). So below we list which images and files should be cached. The CACHE_NAME variable is the name of the cache where our cached files will be stored from now on.

var CACHE_NAME = 'dependencies-cache';
// Files required to make this app work offline
var REQUIRED_FILES = [
'random-1.png',
'random-2.png',
'random-3.png',
'random-4.png',
'random-5.png',
'random-6.png',
'style.css',
'index.html',
'/', // Separate URL than index.html!
'index.js',
'app.js'
];

So we move on to the next step, which is the caching itself. What we do is install the service worker and use waitUntil() to wait for the CACHE_NAME cache to open and for all our files to be cached; after that, everything is in the cache.


self.addEventListener('install', function(event) {
// Perform install step: loading each required file into cache
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
// Add all offline dependencies to the cache
return cache.addAll(REQUIRED_FILES);
})
.then(function() {
// At this point everything has been cached
return self.skipWaiting();
})
);
});

Step 3: Once everything is cached, we can do whatever we like!

With everything cached in the previous step, we can now do whatever we like, even give the browser different content from what was actually requested (we won’t do that here). So with the fetch listener (a routine that runs whenever our page requests something, e.g. when something on our page is reloaded) we check what has been cached: if it hasn’t been cached we can serve it live, and if it has been cached we pull it from the cache. In our example, if everything has gone well, the content of our page will be available offline too, with no connection, as long as everything has been cached.


self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return the response from the cached version
if (response) {
return response;
}
// Not in cache - return the result from the live server
// `fetch` is essentially a "fallback"
return fetch(event.request);
}
)
);
});

The End!

There is a lot more we could do, for example check whether there was a previous service worker that we want to replace. See the code below:

self.addEventListener('activate', function(event) {
// Calling claim() to force a "controllerchange" event on navigator.serviceWorker
event.waitUntil(self.clients.claim());
});

What we have described above is a basis for starting to work with service workers and understanding how they can help you. It is a starting guide, and you will need to build on it before using it in a real project.

If you would like more clarification, leave a comment in the form below!

Leave a comment

Your email address will not be published. Required fields are marked *

Recent articles

Ελλάδα 2.0 Banner

Free e-book from Web-Mate on local marketing