Your first service worker

It's evening. Kumiko, a young Japanese graphic designer, goes down into the busy metropolitan of Tokyo. While waiting for the Mita line, she browses to one of her favorite websites. The train arrives, Kumiko goes in and in a few seconds arrives in a low network area. Kumiko has no connection, she has to wait for the train to arrive in a good network area to resume browsing. This is, unfortunately, a familiar scene for everyone, whether you are in Tokyo, Milan or New York. We have all faced this problem. And service workers exists to solve this problem.

What is a service worker?

A service worker is a simple javascript script that your browser runs in the background. It runs on a different thread to the main JavaScript that powers your web app. It's async and no blocking, without any DOM access. It includes exciting features like push notifications and requires HTTPS for better security. Another huge benefit of the service worker is to give the developer complete control over the caching experience.

Status of support

Chrome, Firefox and Opera support service workers. Microsoft Edge is on the way. Safari not yet, even if there are hints of good chances.

HTTP Caching vs Service Workers

HTTP Caching is a simple technique that stores a copy of a given resource and serves it back when requested. If a user visits the same resource within one session, there is no need to download again the same resource. The web server uses the Expires header to inform the web client that the current version of the resource is still valid and no new download is required. The browser then caches the resource until the specified “Expiry date”. It will check if a new version of the resource exists by the expiration date.
HTTP Caching can improve response times and reduce server load. At this point, you might think, why do we also need the Service Worker cache if we have HTTP caching?
The HTTP Caching does not allow you to download resources you still have to visit. HTTP Caching can't cache lots of requests. These are just two of the many reasons why service workers are superior to HTTP Caching.

Time to write your first service worker

First of all head over to the repo to go straight to the code. Here is a very simple HTML page that we will use to explain service workers. I've included some nice pictures I downloaded from Unsplash and I used the Tachyons, a simple css toolkit to give some basic styling. Surely you will all know Unsplash, the best platform to find high quality, high resolution and completely free photos. Tachyons is an easy css toolkit for fast prototyping.


If you are online or offline, but you have configured service workers correctly, you will see the page as follows:

Not exactly the same thing if you're offline without service workers

Our plan

First of all, we need to register the service worker. Then we need to configure the service worker to cache index.html, tachyons.min.css and the JPEGs.That's all we need. However, remember that this example is simple and basic. Its purpose is to show how basic caching works with service workers. We will face more complex and realistic examples in the next articles.


Back to us, we need to register our service worker. If the browser supports the service worker,  it loads the service worker file to register it.  If the browser does not support it, it logs the error.

if ('serviceWorker' in navigator) {  
    window.addEventListener('load', function() {
        navigator.serviceWorker.register('service-worker.js').then(function(registration) {
            // Registration was successful
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }, function(err) {
            // registration failed :/
            console.log('ServiceWorker registration failed: ', err);
        });
    });
}



Now we create a service worker file we will place in the root directory. Service-worker.js is heavily commented so that you know what each section of code does.

var cacheName = 'your-first-service-worker';

var urlsToCache = [  
    '/',
    'css/tachyons.min.css',
    'img/andre-benz-248755.jpg',
    'img/andre-benz-250740.jpg',
    'img/andre-benz-256762.jpg',
    'img/redd-angelo-230297.jpg'
];

self.addEventListener('install', function(event) {  
    // Perform install steps
    event.waitUntil(
        caches.open(cacheName)
        .then(function(cache) {
            console.log('Opened cache');
            return cache.addAll(urlsToCache);
        })
    );
});

// Fetch the contents and reply with cache
self.addEventListener('fetch', function(event) {  
    event.respondWith(
        caches.match(event.request)
        .then(function(response) {
            // Cache hit - return response
            if (response) {
                return response;
            }
            return fetch(event.request);
        })
    );
});


Conclusion

We have looked into how you can cache some resources using a Service Worker. We have only lighly touched the fetch event which can offer much more powerful use cases. There are wonderful libraries developed by bright people at Google we still need to discover (SW Toolbox & Workbox.js). But we will dive deeper into those things in the next articles.

Keep coding and stay awesome,
nicola