How we made our website offline first


(S/SVR) #1

As a developer, I approach new platform features with a healthy amount of skepticism. But when I first heard about Progressive Web Apps and ServiceWorkers, I was actually excited about the world of possibilities that it could offer. If anyone still doesn’t know what a Progressive Web App (PWA) is, here is a small explanation - it’s a term that is used to make your web app feel more like a native app, and we use something called service workers to achieve this. A Service Worker is a script that runs in the background and is separate from a web page - it opens up a lot of features for our web app such as,

  • Great offline UX
  • Background Sync
  • Push Notifications
  • Good page speed at any connectivity

And with even more functionalities coming soon, it has the ability to make our web app stay as native as possible.

But why do we need all this?

The internet speed in India is not that great to start with and many of the users are still using 2G or something that’s even worse. In order to compensate for these users and to provide a general good user experience on any speed (even offline) we have to include these functionalities.

However, now the internet speed in India is getting increasingly fast. According to a report in Q4 2016, the average internet connection speed in India was 5.6Mbps - a 36 percent rise quarter-to-quarter and a stellar 99 percent increase year-on-year. (Source). So we are on the rise but we still have a long way to go.

Source

So while India aims for the best and reliable connection speeds we should aim at providing our digital experience much more quickly.

So, what exactly falls under the criteria of PWA and offline first?

Well, you can say that different users might have different goals working with service workers. Similarly, my goals while working with service workers were to,

  • Make the whole website offline first
  • Give push notifications to updates on our blog
  • Implement the “Add to Home screen” functionality to Android devices

First let’s make everything accessible offline

To do that we have to add a service worker - currently, some of the browsers support service workers but if something doesn’t support them, then no change or error would occur.

Source

Google developers have been pushing service workers so much so that they even have extensive documentation on how to set it up! The gist of this documentation is that we have to install a service worker which will get updated (in the background) and cache’s all the content in that’s in our site. To learn more take a look at this.

In sw.js

self.addEventListener('install', event => {
  // Do install stuff
});
self.addEventListener('activate', event => {
  // Do activate stuff: This will come later on.
});

In index.html

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw-7092fe85.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);
    });
  });
}

Add these two code in your project directory and if you did everything right up until now, you should be able to see a “ServiceWorker registration successful” message in the console. To learn more on how you can implement cache functionality in your site take a look at -

  1. Service Workers: an Introduction
  2. Service workers explained
  3. Caching with service workers, the easy way
  4. Making a Simple Site Work Offline with ServiceWorker

After you’ve completed everything and added a working and cacheable service worker file to your web app you can measure the difference in speed that it has given. You can see our site’s Service Worker file here. Now let’s see what difference in speed our site has after implementing service workers -

With perfect connection on the first load,

With perfect connection on Reloading,

With a slow connection,

With Lie-fi connectivity,

And when completely offline,

Lie-fi means that the connection is very unstable, but the browser still thinks that a perfect connection has been established. As you can see, we now have a good offline experience and a custom screen will be shown even when no internet is available. And just like that, our site is available offline first and is available even on flaky connections.

With that done, let’s now look at Push Notifications.

Push Notifications

When a user allows our site to show notifications, we can show a web notification about new updates on our blog - it can be done by adding this code to the directly available service worker js.

But we have to ask the users for their permission and we should make sure that the users subscribe to our notifications - this can be done by adding it to our service worker.

function initialiseState() {
  if (Notification.permission !== 'granted') {
    console.log('The user has not granted the notification permission.');
    return;
  } else if (Notification.permission === “blocked”) {
   /* the user has previously denied push. Can't reprompt. */
  } else {
    /* show a prompt to the user */
  }
  // Use serviceWorker.ready so this is only invoked
  // when the service worker is available.
  navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.getSubscription()
      .then(function(subscription) {
        if (!subscription) {
          // Set appropriate app states.
          return;
        }
      })
      .catch(function(err) {
        console.log('Error during getSubscription()', err);
      });
  });
}

This is the anatomy of the subscription object,

{  
  "endpoint": "https://example.com/push-service/send/dbDqU8xX10w:APA91b...",  
  "keys": {  
    "auth": "qLAYRzG9TnUwbprns6H2Ew==",  
    "p256dh": "BILXd-c1-zuEQYXH\\_tc3qmLq52cggfqqTr\\_ZclwqYl6A7-RX2J0NG3icsw..."  
  }  
}

Once that’s done, we can now push notifications to anyone accessing the site and even give permission to them.

PWA (Progressive Web app)

And finally to make it a full-fledged progressive web app, we have to add a manifest file to the root directory and then add this meta tag to our HTML files.

<link rel="manifest" href="/manifest.json">

In the manifest.json file, we should then specify how our site will work as a stand-alone web app.

{
  "name": "Skcript | Artificial Intelligence & Machine Learning powered business applications.",
  "short_name": "Skcript",
  "icons": [{
        "src": "https://www.skcript.com/images/brand/skcript_logo.png",
        "type": "image/png",
        "sizes": "128x128"
      }, {
        "src": "https://www.skcript.com/images/brand/skcript_logo.png",
        "type": "image/png",
        "sizes": "152x152"
      }, {
        "src": "https://www.skcript.com/images/brand/skcript_logo.png",
        "type": "image/png",
        "sizes": "144x144"
      }, {
        "src": "https://www.skcript.com/images/brand/skcript_logo.png", 
        "type": "image/png",
        "sizes": "192x192"
      },
      {
        "src": "https://www.skcript.com/images/brand/skcript_logo.png",
        "type": "image/png",
        "sizes": "256x256"
      },
      {
        "src": "https://www.skcript.com/images/brand/skcript_logo.png",
        "type": "image/png",
        "sizes": "512x512"
      }],
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "orientation": "portrait",
  "background_color": "#000000",
  "theme_color": "#000000"
}

This is the manifest file that we used in our site - you can modify it further according to your liking and then even customize it!

If all the things mentioned are present, then the service worker will show a banner to the returning visitors about adding our site to the home screen

If the user clicks ‘Add an icon’, the app will be added onto the home screen and we will have a custom splash screen for our offline web app.

Initially, we were on a bit of a learning curve as we were just getting to know how service workers function, but this learning is something that has helped us make our site way better. And if you’re interested in learning more about this, you can check out these useful links below.

  1. The Service Workers API
  2. W3C Service Worker
  3. Many Recipes and good practices for Service Workers
  4. Even more examples by Google
  5. A Simple Service Worker App
  6. Offline Recipes for Service Worker

Checkout this chrome extension to check if everything is working properly

So, that’s how we made our website as a Progressive Web App folks!

Try it for yourself! Go offline right now and travel back to our homepage! 🎉

Or let us build a website for you!


This is a companion discussion topic for the original entry at https://www.skcript.com/svr/offline-is-the-new-online/