July 18, 2016
  |   AEM, Technical Development

Getting Started with Service Workers in AEM

Here’s a story we can all relate to: You’re browsing your favorite site, and a notification pops up – “Try our new mobile app!” You shrug, and decide to give it a try. Unfortunately, the experience is almost always the same. The application is slow, bug-ridden, a battery hog, and overall a nightmare to use. These problems aren’t present in the site itself, so why use the mobile application at all? Because we’re not always connected to the internet; and native applications can give us some offline functionality, such as viewing old conversation logs. Webapps can’t offer that offline functionality.
But, as it turns out, this is no longer the case. A new JavaScript-based technology called service workers has emerged and it is currently supported by most major browsers. These powerful tools grant a greater degree of control over web pages more than ever before. Best of all, one of the many features they introduce is, you guessed it, Offline webapps. Before we dig into specifics, it’s worth going over the basics of how service workers function.

Setting Up Service Workers

Registering a service worker is fairly trivial: Just call navigator.serviceWorker.register() from a page and tell the function where your service worker script is. Once that’s done, your script will be installed and ready to do its job. Here’s an example of what that might look like:

Note that the script’s location is important! For security reasons, service workers can only control pages that are in a subdirectory of their containing folder. This helps prevent common exploits such as cross-site scripting manipulating what gets loaded from cache. Thus, if you have a service worker that you want to use on every page, you’ll need to put it in your server’s root directory.
The service worker script itself typically consists of little more than several JavaScript event listeners. These wait for specific events, such as fetch calls or messages from a page. When those events fire, the service worker can step in to work its magic. For example, when the onfetch event fires, you can tell a service worker to retrieve the resource from its cache, or return a completely custom resource. What the service worker ultimately does is completely up to you, but with the number of tools they come with and the options they offer are limitless. Jake Archibald has published several great examples, such as a Wikipedia webapp and Emojoy.

Behind the Scenes

You might think this doesn’t sound so revolutionary. However, much of the beauty in service workers is just how low maintenance they are. You’ll find that updating is a painless process. Once installed, service workers will periodically check for newer versions of themselves. If there is an update, it will be queued for installation once all of the pages it controls are closed. Users can also force scripts to update by performing a hard page reload. If you need to clean up after your old script (such as clearing caches, for example), this is easily handled via an event listener on your page.
In addition, service workers can continue to run and execute across multiple pages, even if those pages aren’t currently active. This opens up all sorts of interesting possibilities for communication between pages and a user. Push notifications are one great example of a native app feature that service workers bring to the web.

Trying it Out

So we’ve got a basic understanding of service workers and why they’re significant. Now let’s take a look at a practical example. Service workers make offline-first applications possible with a sophisticated caching system. This is not a radically new feature, but a much simpler and more flexible alternative to previous caching methods. Since service workers can trigger event handlers on fetch calls, we can intercept those requests and customize what’s returned to the browser. Here’s a simple code snippet to illustrate the idea:

Here’s what’s going on: First, we set up an event listener for when the service worker installs. When that event fires, we set up a simple anonymous function to respond to it. That function opens up the service worker’s cache and adds whatever we want to to it. Here, items refers to an array of URLs pointing to the resources we want to cache. Disk space permitting, you can cache as many resources as you like.
That’s it for caching. Now we just need to retrieve them when they’re requested:

As before, we want the service worker to wait for an event—this time, a fetch call. When that happens, we intercept the request and check our cache to see if we have that resources. If we do, then we retrieve the resource from the cache and return it to the page. Otherwise, we let the fetch call continue.
That’s it! Believe it or not, this script is a fully-functional service worker. All you need to do is register it on another page. Then, whatever resources you put in items will be cached next time you load the page.
Remember that this is just a simple example of what service workers are capable of. There are many other tasks you can delegate to them. The MDN hosts an excellent API that covers the possibilities, and is a great resource for sharpening your skills.

Subscribe to Our Newsletter

Get the latest insights from Blue Acorn iCi

Let's build something together.