How to use service workers in progressive web apps
Service workers are scripts that run in the background in the user's browser, enabling such features as push notifications and background synchronization. There are many ways that you, as a developer, can use them, and I've compiled all of those here, along with an explanation of the overall scope and resources you'll need to develop any type of progressive web app (PWA) focusing solely on service workers.
I've been working in web development and app development as a project manager and developer for several years, and service workers, along with the rest of what PWAs are all about—namely an app shell loaded by an app manifest—are one of the more promising concepts I've seen. Progressive web apps, when combined with service workers, provide better performance and a better overall user experience.
Service worker basics
Here's the basic rundown on service workers. But if you have never encountered progressive web apps before, or if you need to read up on the topic, visit Google's developer pages for a primer.
The service worker interacts with the client's browser page and HTTP Get/Post/Set requests. This means you can intercept these requests and either let them go through to their original endpoint or alter them to suit your needs. One obvious use for this is to have a service worker check whether the client has access to the Internet.
If it doesn't, then the service worker script can reroute the requested URL to a cached version of that URL. And because progressive web apps use an app shell, everything is cached for you.
This means a service worker can tell the client that it should fetch the cached version of the page instead of failing to connect to the Internet.
The above example is just a small part of what developers have done with service workers. This is also one of the most popular uses, but it's possible to do much more than just cache content. For example, you can run a virtual server on a service worker and Node.js stack or have the script function as a load balancer.
Registering a service worker
Once it's registered and activated, there are no further requirements for the service worker itself. But just registering it isn't enough, since at this point it doesn't do anything. So here are some of the features for which developers use service workers.
Handling cached content is one of the most common uses for service workers. For a head start, review the Google Chrome documentation, or that of Mozilla. Here's a full cache, update and refresh example.
Enabling offline functionality is quite possibly the single most sought-after service worker feature. Some examples just show how to load a simple static HTML page, while others build mini-games such as Sudoku into their offline pages.
- Content delivery networks
Handling CDNs and other external content can be tricky. Often, developers opt out of externally hosted content due to SSL and same-origin policies, but you can actually import scripts from CDNs.
- Push notifications
Serving push notifications is a great way to interact with customers and visitors. See the Web Push Book for more.
- Performance enhancement
There are plenty of showcases on Google's developer sites that show real-world data from sites running PWAs with service workers. Tweaking the performance further with HTTP2 Push can be an excellent choice.
- Loading cached content for new users
You can even write some code to make first-time visitors fetch the cached content and app cache, rather than traditional browser caching, in which everything is downloaded by way of get requests.
- Load balancing
While you might not automatically consider a service worker as a load balancer, there are already implementations of this that exist in real-world applications, even if a service worker is not the most obvious choice for the job.
- Background synchronization
Background synchronization is another extremely powerful feature. For more, read Dean Hume's guest post on the subject.
Since you can run background tasks, you can even play around with native app-like features, such as this geo-fence example.
Developing service workers
There are a few things that you should know before developing service workers. Here are some commonly used resources and tools you can employ.
For developers, many people have added console debuggers that are more or less permanent to help with troubleshooting, since the serviceworker.js runs its own browser instance that's separate from the page you're on. Examples include:
Libraries and tools
This library, maintained by the Google Chrome team, delivers a set of tools for managing content caching, third-party resources, and more. Read "Getting started with sw-toolbox" and "Improving UX with sw-toolbox" to get a deep look at how to use this library.
Developed by the Google Chrome dev team, this tool set lets you manage the pre-caching of resources and has an option for cache-first, which serves first-time users of the cache as well, improving performance and load speeds.
This not only serves as an easy way to implement Google Analytics in offline mode, but also shows how to temporarily handle data. It works by temporarily storing the data and retrying connection attempts to push data, if successful.
- Manifest generator
The web app manifest is a simple JSON file containing key data related to the progressive web app. While not directly related to the service worker, this generator tool can come in handy when combining the service worker with the app shell.
- Web App Manifest specification
Both service workers and progressive web apps are subject to daily commits and changes, so it's wise to refer to official documentation as often as possible to keep up to date.
- Pinterest's service workers GitHub repo
This is a collection of utilities for creating, testing, and experimenting with service workers.
- While this cache polyfill example is obsolete in the sense that the latest versions of both Chrome and Opera use Cache.andAll, it can still serve as an example for implementing other polyfills.
- Another great example comes from Maximiliano Firtman, who made a polyfill example to experiment with the amount of code you can already run on iOS, compared to things that Apple needs to implement.
- Google's Polymer App Toolbox provides a solid base for building complete progressive web apps.
By default, PWAs require a secured HTTPS connection to prevent man-in-the-middle attacks. That's somewhat ironic, since you could consider the service worker as a man-in-the-middle script itself.
This requirement also aligns very well with what Google envisions for the future of web pages, which is an SSL-secure web space.
Defining the scope is also important and should ideally only cover the files needed to serve everything vital and necessary to displaying the sites, as opposed to just including an entire web framework such as Laravel or Ruby on Rails. Try looking into a scope to registration map if you're dealing with a larger framework implementation.
Note that you can't use a content delivery network for the service worker itself, and while you can import via importScripts(), most developers I've talked to prefer keeping things with the same origin, as opposed to a remote origin. There are of course fixes for CDNs and other clever rerouting techniques.
For a few companies, this technology will make a huge difference to the bottom line, due to increased performance and conversion rates. But for most online websites and businesses, this will be a slow process, and service workers will be adopted over time.
As we continue to focus more on good UX and top performance, I expect to see PWAs and service workers seep into the ecosystem of the Internet, silently enhancing the user's browsing experience.
Of course, if at some point Apple asks the Safari browser team to implement this API integration, you'll see a surge, as people and businesses that previously held out begin to enter this arena.
Now you're ready to get started
The overall addition of service workers and progressive web apps is a big implementation for HTML browsers, and this API gives you immense access to functions by way of the browser that don't just focus on one area.
It's time to get started. See my recommended links below for further reading and inspiration. I look forward to your comments and questions.
- Stuff I wish I'd know sooner about service workers
- Service Workers and base URI's
- ServiceWorker Cookbook
- Is ServiceWorker ready?
- Upgrading your Service Worker cache
- Google Chrome's Service Worker snippets on GitHub
- Mozilla's free plugins for WordPress Service Workers
- Design and specification for Background synchronization
- W3C Push API (Editor's draft)
- Grunt can also be used together with Service Workers
- Your first Progressive Web App on Rails