Caching with service workers, the easy way

Caching

Caching is one (just one) of the things that service workers do really well. A good caching policy enables your web app to do some pretty cool things, like serving almost instantaneous responses, smoothing over patchy network connections, and even providing offline functionality. With the right caching you can banish 404 response pages to the annals of web history.

If you want to go nuclear in terms of performance of your web apps, check out our amp-install-serviceworker article, although this will require a bit more commitment to get set up. Or if you want a more nuts-and-bolts look at service worker caching, without the use of helper libraries, then see our Taking the web offline with service workers article. In this article, we’re just taking a look at the easiest and quickest options to get some caching into your existing website.

But is there a really simple way to implement caching with service workers right now? Let’s find out.

sw-toolbox

Probably the most versatile and easy-to-use library to help you is the sw-toolbox library. It offers a simple way to achieve the most common caching and routing tasks that you might need. The sw-toolbox is open source and you can grab it in one of the following ways:

To use sw-toolbox you’ll need to deploy it with your project.

So, first we’re going to write a short JavaScript file—the service worker—and save it as sw.js. You can find out more about service workers here, but right now you can think of them as programmable caching and routing network proxies that can intercept and manipulate network requests whatever way you like.

In this example we are going to save sw.js under the caching directory, to keep it separate from other examples we host. Since the location of this file determines its scope (i.e. what directories it has control over), you might prefer to save it at the root / directory of your web project.

To import sw-toolbox into your service worker, add the following line to the top of your service worker source (your path might be different depending on how you installed sw-toolbox):

Caching strategies

The sw-toolbox offers several out-of-the-box caching policies. These include:

  • networkOnly – only fetch from network
  • cacheOnly – only fetch from cache
  • fastest – fetch from both, and respond with whichever comes first
  • networkFirst – fetch from network, if that fails, fetch from cache
  • cacheFirst – fetch from cache, but also fetch from network and update cache

These behave more or less as you’d expect, as summarised above. There are subtleties though. For instance, fastest will always make a network request, and if there is something new on the network, then the cache will be automatically updated. You can read all about these strategies in detail in Jake Archibald’s Offline Cookbook.

So, how to implement one of these in your app? Easy, just add the following line to your service worker code, for example:

We’ll choose cacheFirst here, as it’s a good fit for a blog type site. If you don’t get the latest content this time, you’ll get it next time.

So that’s the service worker: it can cache some resources, and we’re now serving those cached resource. With this caching strategy, whenever an item is retrieved from the network, the cache is automatically updated.

The full service worker code, all two lines of it, is here:

Now we just need to add the service worker to our HTML page, and we’re done. Add this code to the head of your HTML document and you’re good to go:

Precaching

With the setup above, the following sequence occurs:

  1. First page request – handled by server, web page – service worker installed
  2. Second page request – handled by service worker, makes request to server for content, caches resources
  3. Third page request – handled by service worker, responds with cached resources

So it’s only on the third page request that the cache kicks in.

A nice way to improve things is to use sw-toolbox to pre-cache some resources. Pre-caching in this context means that any resources you specify will be cached when the service worker is first installed. Good targets for this are things like images, fonts, JavaScript, CSS: any resources that don’t change much. For example, the app shell, the HTML, CSS and JavaScript powering the app UI, is a good thing to pre-cache. This means we can have the cache kick in on the second request, instead of the third.

Let’s say you wanted to cache the homepage, and some resources, you could do so like this:

This is a handy approach for caching items in advance of the user requesting them. This approach becomes even more powerful, if you can install the service worker before the user visits your page. We saw how this could work where an AMP page can install a service worker in a previous article.

Caching with service workers example

You can see this in action on a small example page at https://mobiforge.github.io/caching. The network tab of the Chrome developer tools is shown below, after the second page load. Note that it reports the various assets are delivered via the service worker: the app is cached!

Caching with service workers

One final point to note for the performance-obsessed among us who worry about the impact of including the sw-toolbox library: it will add just 6.9KB; a pretty minimal, one-time hit with a big payoff. Definitely worth it!

You can find the full code example on github.

Leave a Reply

Exclusive tips, how-tos, news and comment

Receive monthly updates on the world of mobile dev.

Other Products

Market leading device intelligence for the web, app and MNO ecosystems
DeviceAtlas - Device Intelligence

Real-time identification of fraudulent and misrepresented traffic
DeviceAssure - Device Verification

A free tool for developers, designers and marketers to test website performance
mobiReady - Evaluate your websites’ mobile readiness

© 2024 DeviceAtlas Limited. All rights reserved.

This is a website of DeviceAtlas Limited, a private company limited by shares, incorporated and registered in the Republic of Ireland with registered number 398040 and registered office at 6th Floor, 2 Grand Canal Square, Dublin 2, Ireland