Progressive Web Apps(PWAs) are normal web apps that appear to the user like native mobile apps. They do this by loading instantly and reliably in every network condition even offline, Engage the user with features like push notifications even when the user has left the app or closed the browser.
Requirements
PWAs load even when offline with the help of a service worker, The service worker script is used to cache the resources and serve resources from the cache when there is unstable or no network. To use service workers, your site needs to be HTTPS. You don’t need to buy a SSL certificate, you can install Free SSL certificate for your site by following this post .
Service Worker
Service Worker is a script that runs in the background, It does not have access to the DOM, It can communicate with the rest of your website using the POST Message method.
Service workers have their own lifecycle which is independent of your website. To use a service worker, you first need to register it. You can register the service using the following code
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/serviceWorker.js').then(function(registration({
console.log("Service Worker Registered");
}, function(e){
console.log('Registration failed: ', e);
});
});
}
The above code first checks whether serviceWorkers is supported by the browser. You can find which browsers support service workers here. Next the code registers the serviceWorker script placed at the root of your website’s directory.
Fetch and Caching
Service workers can be used to intercept all network request that your site makes. You can use this to intercept network requests, store the resources in cache and then return the resource. Service Workers can intercept network request using the Fetch Listener.
self.addEventListener('fetch', function(event){
console.log(event)
})
once you receive a fetch request for a resource, you can retrieve it from the network as shown below
self.addEventListener('fetch', function(event){
event.respondWith(fetch(event.request));
})
The above code calls the respondWith function which is used to respond to the fetch request by fetching the requested resource from the network and returning it.
The code so far has only intercepted requests and returned the resource from the network which is not very useful, now we will discuss how to cache the resources and serve them instead so that the site loads even when there is not network connectivity.
We will use the Cache API for caching resources in the browser cache. To store resources in a cache, you need to first create a cache store, we can create a cache store using the following code
caches.open("v1")
The above code opens a cache store named v1, it creates it if the cache store doesn’t exist. It returns a Promise , you can then add items to the cache using the cache.put() method, the cache.put method takes in 2 parameters, the name and the resource to cache.
Now that we can put resources in the cache, Its also helpful to know whether a given resource is present in the cache or not, we can do this using the caches.match() method, an example is given below
self.addEventListener('fetch', function(event){ event.respondWith( //check if item is in cache caches.match(event.request).then(function(response){ //item in cache so return it if(response){ return response; } //item not in cache so fetch it return fetch(event.request).then(function(res){ return caches.open(CACHE_NAME).then(function(cache) { cache.put(event.request.url, res.clone()); }) }); }); });
The above code, intercepts all network requests, then it checks if the item is in the cache, if the item is in the cache, it returns it from the cache, else it fetches it from the network and stores it in the cache.
There are 2 main problems with the above caching code.
- Items found in cache are never updated, so if you update any resource, the service provider will always show the cached version of the resource, not the new version
- The cached is never cleared, if you have lots of resources or if your website changes frequently, lots of unused resources will be present in cache.
For better caching strategies, you can refer to the serviceWorker cookbook
Push Notifications
Using service workers, you can engage with users even when they have closed the browser using web push, cookbooks on how to implement web push can be found here. You will have to request user permission to display web notifications, One downside is, if a user declines to enable web notifications, then you cannot ask again until the user manually resets your website’s permission. So give the user some context on why you are asking them to enable web notifications as you get only one chance.