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.
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.
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.