The mobile web still doesn’t compare to a native mobile application—You just can’t do smooth transitions, push notifications, or offline accessibility and still be blazing fast. But recently, due to a new technology called Progressive Web Apps (PWA), we can aspire to have native app-like experiences in our websites, too. If you don’t know what a Progressive Web App is, it’s used to make your web app feel more like a native app, and you use service workers to achieve this. A service worker is a script that runs in the background, and is separate from a webpage. It can be used to make amazing stuff like:
-
- Background Sync
- Push Notifications
- Great offline UX
- Great page speed with any connectivity
As its name suggests, a Progressive Web App will progressively improve user experience. However, when users are on unsupported browsers, it will gracefully ignore these optimizations. That’s the power of PWAs. There are no set goals to achieve. You can just improve and increase the features of your site, and it will only make an impact on those web browsers which support it.
I’m going to take my site and make it a Progressive Web App just for fun. You can see the final code here.
Secure Your Website
HTTPS is the gold standard of web security. But it’s not just about security. Without HTTPS, service workers will not work, since Progressive Web Apps can not be served from an insecure origin.
Add the Manifest
Once you are sure about HTTPS, you can move on to adding a manifest file. This manifest file tells the browser about all the meta information that will be needed for the PWA.
First, add the file to all of your HTML files with a link tag like this:
This will link you to your manifest.json file, which looks like this:
{ "name": "Swaathi Kakarla | Usually about code, but not always", "short_name": "Swaathi", "icons": [{ "src": "/public/icons/favicon-128x128.png", "type": "image/png", "sizes": "128x128" }, { "src": "/public/icons/favicon-144x144.png", "type": "image/png", "sizes": "144x144" }, { "src": "/public/icons/favicon-152x152.png", "type": "image/png", "sizes": "152x152" }, { "src": "/public/icons/favicon-192x192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/public/icons/favicon-256x256.png", "type": "image/png", "sizes": "256x256" }, { "src": "/public/icons/favicon-512x512.png", "type": "image/png", "sizes": "512x512" }], "start_url": "/", "scope": "/", "display": "standalone", "orientation": "portrait", "background_color": "#202020", "theme_color": "#202020" }
You can learn more about the manifest file in the Web Fundamentals guide by Google.
Finally, the Service Worker
A service worker is basically a Javascript file that acts as an intermediary between the browser and the network. This gives us access to control the network flow and assign which request goes where. There are lots of other benefits to this service worker file, like push notifications, offline support, aggressive caching, and more!
Let’s now focus on the lifecycle of a service worker file:
When the website first fires up, there will be no service worker installed, obviously. However, after the page loads, it gets installed along with two markers—The current page and the default value for state (‘Activated’). As the user navigates the website, the requests get piled up in the service worker, which then decides if it should go to the network, or fetch from local cache! It’s as simple as that. Here are a few resources I found helpful when researching service workers:
Let’s now add the final bit:
In index.html:
if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); }
In service-worker.js:
self.addEventListener('install', event => { // Do install stuff }); self.addEventListener('activate', event => { // Do activate stuff: This will come later on. });
So, in the service worker file you can cache, redirect network requests, and even specify the offline pages. A PWA is essentially a really powerful service worker.
Let’s see how this would be handled in a mobile browser:
When the user first loads the website, the browser will ask to add it to their home page. If the user agrees, they will go through custom splash screens before the app (‘website’) loads. You can also set the home screen icon!
To learn more about service workers and their awesomeness, I’d recommend checking out:
And that’s it! You now have a site that is considerably faster and will act as a stand-alone app in mobile devices.
You can use the Audits tab in Chrome DevTools (which uses Lighthouse) to validate and measure your implementation.
To compare, this is before installing the service worker:
And after:
And that’s how you make a Progressive Web App! Though the implementation varies when you’re trying to turn a dynamic website into a PWA, this should help you get started.
So get cracking and turn your site into a PWA today!