Achieving network-independence and native app-like experience using Service Workers | PWAs

Comments · 2754 Views

This blog provides insights about a new software development methodology called Progressive Web Apps (PWAs). Using this design pattern, we can build applications that are faster, network-independent, and provide a native app-like experience. Also, included is a link to my full progressive

Service workers:

Service workers act as proxy servers that sit between the browser and the network.

Their primary task is to:

  • Intercept the network requests.
  • Perform cache fetch or updates.
  • Take required action when the network is available again.

Registering a Service Worker:

navigator.serviceWorker.register(sw_file) registers a service worker to an application. Such registration can be performed when the window is loaded.

Registering a Service Worker:

if ('serviceWorker' in navigator) {

    window.addEventListener('load', function() {




Cache Store and URLs:

After a service worker is registered, we can define all the URLs that will be cached upon the first user interaction.

Creating a cache store:

var CACHE_NAME = 'my-profile';var urlsToCache = [  '/',  '/index.html',  '/images/profile.png',  '/style.css',  '',  '',  ''];

Install event and Cache.addAll():

Install event is fired when the service worker or the downloaded file is found to be new. If an existing service worker is detected, installation works in the background but is not activated. Activation is only performed when there are no web pages that are referring to the old service worker.

Cache.addAll() takes an array of URLs and adds the resulting objects to the cache.

Adding URLs to cache:

self.addEventListener('install', function(event) {  event.waitUntil(      .then(function(cache) {        return cache.addAll(urlsToCache);      })  );});

Intercepting network requests using fetch event:

Fetch event is raised when a fetch operation happens in the web application. Users can add an event listener to fetch events and then respond with contents from the cache. If the cache does not have the resource, the request can be served from the network.

Below are some interception strategies:

  • Cache only: serve requests from cache only.
  • Network only: serve requests from the network only.
  • Cache - First: serve requests from the cache if required fallback to network.
  • Network - First: serve requests from the network, if required fallback to the cache.

Implementing Network - First:

self.addEventListener('fetch', function(event) {  if(!(event.request.url.indexOf('http') === 0)){    return  }  event.respondWith(  fetch(event.request)    .then(function(res) {      return        .then(function(cache) {        cache.put(event.request.url, res.clone());        return res;      })    })    .catch(function(err) {      console.log("using cache")      return caches.match(event.request);    })  );});

Cache.put() can be used to insert or update cached resources whereas Cache.match() can be used to retrieve resources from the cache.

Adding an app shortcut:

To add an app as a shortcut, we need to provide a manifest.json file with all the shortcut and icon details.

manifest.json file:

{    "name": "Profile",    "short_name": "Profile",    "start_url": ".",    "display": "standalone",    "background_color": "#fff",    "description": "Satvinder's Profile",    "icons": [{      "src": "images/homescreen.png",      "sizes": "512x512",      "type": "image/png"    }]}

Viewing app offline:

Offline mode can be simulated in Chrome by navigating to the Application tab and then selecting Service Workers in Dev Tools.

Viewing app pffline

My progressive GitHub profile