Using service workers to better handle going offline

What is a service worker? It’s not someone who works on services, although I’m sure you probably already had that figured out 👀. Here’s a handy explanation of a service worker written by Matt Gaunt, Developer Programs Engineer at Google:

“A service worker is a script that your browser runs in the background, separate from a web page, opening the door to features that don’t need a web page or user interaction. Today, they already include features like push notifications and background sync.”

If you need an example of what a service worker can do, log in to Facebook and accept the box that prompts notifications. You now get notifications about Facebook, without actually needing to be on the website. That’s all achievable by creating a service worker. In effect, service workers simply allow websites to do things without the user needing the website tab open.

When wifi or internet drops out, this can lead to a frustrating experience for the user. One of the great uses of a service worker is that it allows developers to “hijack” what happens when connections are lost, giving us some level of control over what we describe as the “offline experience”.

It’s this ability to improve the offline experience that we’re utilising on our builds here at Neptik. Service workers are, thankfully, not too treacherous to get your head around. There’s a few pre-requisites:

Site must be HTTPS – service workers will only work via SSL encrypted connections. Because service workers hijack the connection between the browser and the server, this is for security purposes. However, when testing locally, you do not need SSL.

Browser Support – improving all the time with solid support across Chrome, Firefox and Opera. For Safari and Edge, service workers are in development.

🗒 Register the service worker

This is your first step, and it involves popping the snippet below within your site’s footer, inside script tags.

Once you’ve done so, reload the page and head on over to chrome://inspect/#service-workers in Google Chrome. You should see your service worker show up as registered.

💾 Install Event

The first thing you want to kick-off within your service worker is an install event. For caching, it’s within this event where we want to open the cache, insert our files, and then check if we have cached the required assets. The install event itself looks as follows:

You may want to define your required assets within an object:

For a recent project, we started off with a Google service worker and we adapted the install event as follows:

This script in effect grabs an offline page (created in the CMS), caches this, and then caches the fundamental assets required for this page to work.

🏃 Fetch Event

Now we want our fetch event. The fetch event is where we’re returning our requests. In a nutshell, the service worker is checking the cache when a request is made. If the asset is identified in the cache, the cached copy is loaded. Otherwise, the service worker passes up the request to the network.

In this example, there’s a couple of checks going on. First of all, we only want to call respondWith() if the request is a “navigate” request. This request mode is not widely supported yet, so we double check by checking the request is a GET request. We’re then using fetch() to throw a catch callback exception in the event that the server is unreachable (in other words, we’re offline). It’s at this point we want to check our cache to and dish up our offline experience.

📸 Activate Event

Despite using the name activate, what we’re really doing here us updating our service worker cache.

We’re firstly checking our pre-defined cache object to delete anything that doesn’t match. We’re then looping to delete whole caches that also do not match what we’ve defined earlier on. We can do this by affixing a version number to our object name for the cached assets like so const CACHE_VERSION = 2;.

Once we have a service worker running, the end result could be something like this:

It’s pretty basic, but it’s a heck of a lot better than an abrupt and irrelevant offline browser page. We could go further, our offline page could contain interesting content that keeps the user engaged until their connection returns.

Only the beginning

This is early days for service workers, and what we’re seeing is only the beginning of what’s achievable. Service workers can not only be used to elegantly handle an offline (or poor connection) experience, but they can also be used to perform other background tasks outside of the tab window. An example of this might be a background sync of data.