PWA: Make your website available offline
If you visit my website from a mobile device, you might notice the following message at the bottom of the screen. No, I am not trying to hack you. I have made my website a progressive web app and, as such, it can be installed in Android and iOS devices and it can be accessed offline. Keep reading if you want to turn your website in a PWA in less than 15 minutes!
The magic behind the progressive web apps are the service workers. To cut a long story short, a service worker is a script that the browser runs in the background, in a separate thread from the UI, providing additional features such as the ability to intercept and handle network requests as well as managing a cache of responses. In fact, this is the only feature we will need to make our website available offline.
The register method tells the browser to search for a service worker in the sw.js file and will start the install step in the background. Thus the next thing to be done is to tell the service worker what to do during the install step which, typically, will consist in caching some static assets.
There are multiple caching strategies to choose from when it comes to service workers and they are all very well explained in the offline cookbook. Take a look at them to know which patterns there are and which ones suit better your application needs (you might apply different strategies depending on the type of resource being cached and how often they get updated). I chose the Network falling back to cache strategy for my webpage for the following reasons:
- Simplicity. There are better performing strategies (e.g. Cache then network or Cache & network race) but they add more complexity to the service worker implementation. Let’s keep in mind that the only goal of this exercise is to make the website available offline, not to optimize the time to content
- I first started with cache falling back to network for better performance but, given I frequently update the application, I was getting errors due to old versions of static assets being cached. Feel free to dedicate some time to solve those errors but, again, the purpose of this tutorial is just to make the website available offline
So, without further ado, let’s implement the service worker. First we need to add a specific set of files to the cache during installation. If all the files are cached successfully, then the service worker becomes installed and we get those static assets available in the cache. If any of the files fail to download and cache, then the install step will fail and the service worker won’t activate (not the end of the world though, it will try to install again the next time the page is loaded).
The shorter the list is the least chances the installation has to fail (and the rest of assets can be cached later on anyway). In my case, I am only caching the landing page of my site. The self property is a reference to the WorkerGlobalScope (available only in service worker threads):
Now let’s get the work done! The most important part of our service worker is the fetch listener. This handler will intercept every network request and will allow us to serve a cached version of a given resource, which, due to the Network falling back to cache strategy, will happen only if the corresponding network request fails (lines 35–38). Don’t forget to add the asset to the cache on a successful network response in order to keep the cache content updated (line 31). The clone method is required because the responses can only be consumed once.
Optionally, an activate listener can also be defined in order to run some tasks each time the service worker is successfully installed. This feature comes handy to clear the application cache every time the service worker is updated. You don’t need to do this but remember the universe tends to disorder and is our duty to keep the application clean and tidy; remove the files you are no longer going to need and make the users happier by freeing space up in their devices.
Once the server worker is put into place the browser will start caching every network request. You can have a look at the contents of your application cache in the Application tab of the Chrome Developer Tools. Once all the content you need has been cached, you can also test the application offline behaviour by checking the Offline box and refreshing the page. Notice how the network requests fail and the assets are served from the service worker:
Congratulations 🎉 Your application just turned offline friendly! You are free to go playing now but stick around because I still have something cool to show you. See that manifest.json file inside the head tag of the HTML page? It has nothing to do with the service worker, but it will make your application installable in mobile devices for free and it only takes a few mintues to add it. It’s content is self-explanatory:
That’s the end of it! As promised, you can turn your website into an offline available progressive web app in less than 15 minutes. Reach me at email@example.com if I haven’t been clear enough about any aspect and good luck turning your website into a PWA!