Published
August 28, 2015
Author
Chris Roberts
Category
Comments
Time To Read
Estimated reading time: 4 minutes

The Service Worker

By Chris Roberts in Client Side Web on August 28, 2015 |

On Monday many weeks ago I had the opportunity to present a 20 minute talk to fellow Javascript developers at the local JS meetup here in Brisbane, Australia (BrisJS). The topic I presented was an introduction to the Service Worker browser API and how it could be used in an “offline first” methodology.

I thought I would share with you some of the things I learned about service worker while putting together this presentation.

Offline first

Offline first is the idea that the experience we deliver to our users should scale depending on the quality of the connection; from no network at all, to patchy mobile connection,  all the way up to a lightning fast fixed cable. It is a form of progressive enhancement that delivers your webpage with the assumption that the user has little or no network connection and builds from there.

The first building block could be as simple as a block of text saying “Having difficulties connecting, please try again when you come back online” which is a slightly better experience than, for example, the Chrome T-Rex:

webpage-offline-no-way

We already optimise in the client for screen size, performance, and browser features, so why couldn’t we optimise for the network?

Service Worker

The Service Worker API is a recently introduced browser feature that allows developers to start a JS background process in the browser that intercepts communication between the network and your page. It provides an interface for developers that will allow us to create features such as Push Notifications, Background Sync, and Cache management all on the client.

The service worker feature and dev tools are only very new and only really exist at the moment in Google Chrome (soon Firefox), but the ideas being generated through the work in this space have the potential to shift how we deliver content to our users.

My experiments with Service Worker have been using it to manage an offline cache of a previously visited document and serve that cache if the network is degraded. I’ll run through a short demo that I presented:

Service Worker code example

The first step is to register a service worker script on a page of your website. This starts the background process with the service-worker.js script. You can inspect this process in Google Chrome using their new inspect tool: chrome://inspect/#service-workers

...
  <script>
    (function() {
      // no service worker for you!
      if (!('serviceWorker' in navigator)) return;
 
      // create the worker
      // note: location of the script defines the scope of the worker
      // i.e. this script has scope over the / path
      navigator.serviceWorker.register('/service-worker.js')
        .then(function(registration) {
          console.log(registration.scope);
        }).catch(function (error) {
          console.log(error);
        });
    }());
  </script>
</body>
</html>

Once the registration events have completed, the following script allows you to programmatically interact with the network request and responses.

The following script creates a very simple cache script that will return assets from the cache if they have previously been downloaded, avoiding the network altogether.

// install event fires when registration is complete
self.addEventListener('install', function (event) {
  // using the caches API to create a new cache object
  event.waitUntil(
    caches.open('this-is-the-name-of-the-cache').then(function (cache) {
      // adding items to cache
      return cache.addAll([
        '/',
        '/images/image.jpg'
      ]);
    })
  );
});

// create an event listener for the fetch event
// a fetch event is fired for every single network request
self.addEventListener('fetch', function (event) {
  // create a promise that tests whether the cache contains the request
  event.respondWith(
    caches.match(event.request).then(function (response) {
      // if an object is found in the cache respond with it
      if (response) {
        return response;
      }
      // otherwise, fall back to the network
      return fetch(event.request);
    })
  );
});

At Expedia we can potentially imagine a lot of ways to integrate this new technology. We’re investigating making our Scratchpad feature available offline, or keeping your stored itineraries  offline. Our mobile site for a time experimented with HTML5 app caching as an offline solution, but it was difficult to make sure the right things were kept in cache so the page would render offline properly. Service worker provides a more flexible solution for temporarily degraded network connections and is easier to work into a responsive web site. Speaking of responsive web, as the Service Worker API makes its way into mobile browsers there is a lot of potential for it to provide a consistent model to deliver alternate content on mobile, without the overhead of downloading it only to suppress it.

Further reading

For more information You can check out the slides I presented (warning in advance, there is a fair amount of Brisbane specific humor…)

There are also several other resources you can call on for more information:

I hope you take a few minutes to look into the Service Worker API and what it might provide for your web applications.