Service worker

svmi3195
3 min readSep 7, 2018

--

Service worker is a web worker which helps to control network requests.

How it can be useful?

First of all, for enhancing offline experience for your apps’ users. Normally if users try to navigate web pages when they have no internet, they will see only a blank page with error message. However, by using service worker it is possible to give them cached pages. It is especially useful for people who use unreliable wi-fi on their travels since they don’t have to stare at the blank page each time they get into no-internet zone.

How it works

Service worker intercepts network requests (fetch) and handles them accordingly. For example, it can attempt to get data from remote server, if not successful — return cached version. Or you can add a button “Save for offline” and save some content (for example, an article) in the cache for offline use. Service worker can intercept any request, not just “GET”.

Registration

To be able to use service worker you need to register it. There are two gotchas here:

  1. You must add registration code for each page. That’s because the user won’t always start from your main page.
  2. Make sure your service worker has the right scope. If you place your sw.js file into the root folder, service worker will have access for all pages. If, however, you place it somewhere else (for example, in “js” folder) it might not work for all your pages (or won’t work at all).

To register service worker you make simple js file with the code like:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(function(registration) {
console.log('Registration successful, scope is:', registration.scope);
})
.catch(function(error) {
console.log('Service worker registration failed, error:', error);
});
}

It checks if service worker is supported in the browser and if yes, registers it. If it is not supported, service worker is not registered and users have their usual experience.

Basic example with getting data from cache

If we want to return cached data on some requests, we can create those caches on service worker installation:

self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(
[
'/css/main.css',
'/js/main.js',
'/index.html'
]
);
})
);
});

This happens when service worker is installed. Then on fetch event we can return those cached files:

self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request));
});

This basic idea can be expanded with falling back to network if caches don’t match and then both returning new data for usage and adding it to the cache. Handling can be as specific and as complicated as you need.

IndexedDB

Sometimes you might want to store data on the client side in some kind of database. However, service worker is designed as fully asynchronous, so it cannot use local storage. You’ll have to use IndexedDB. Original IndexedDB is pre-promises, so you might want to use idb package from npm.

PWA — Progressive Web Apps

PWA is a web application which is reliable, fast and engaging. It feels like a native app for users, it can be installed and lives on home screen. Service worker is one of requirements for PWA, others including manifest, icons, short name, brand colors, performance. In many cases service worker will be most complicated part, so if you already have one you can make your application PWA as well.

Gotchas

Working with service workers can be confusing and frustrating since it doesn’t always behave as you expect. Keep calm and google :)

  1. While you are developing remember that you won’t get updated version of your service worker on reload. New service worker normally will be installed only when you close the window and re-open it. Surely, you don’t want to do this to test every little change, so make sure to utilize browser tools.
  2. If you want to get data from network bypassing service worker use SHIFT+REFRESH.
  3. Make sure your service worker has a right scope. Generally it has to be in the root folder.
  4. When service worker is idle it can be terminated to save memory. Of course, to be terminated it should be idle for quite some time, but in real life situations this can happen.
  5. Installation and activation of service worker happens asynchronously and it takes some time. So your service worker might not work at the very moment user opens app for the first time. If you want certain events to take place only when service worker is up and running you might want to add a listener for activation event and enable fetch events only after it fires.

Links

This and this guides were most useful for me when I was working on my service worker.

Udacity has a course about offline apps and service workers.

--

--