Progressive Web Apps: Bridging the gap between web and mobile apps

Unless you’ve been living under a rock, you’ve probably heard of PWAs or Progressive Web Apps. It’s a hot topic right now because it’s support is increasing in multiple platforms, and major companies are deciding to work on PWA versions of their web apps including Twitter, Lyft, Starbucks, NASA, and more.

Recently it gained more attention, when Apple announced Service Worker and Web Manifest support for Safari. Microsoft brought PWAs to the Windows store, and Chrome has experimental PWA support for all the platforms.

Okay that should be enough to convince you that they’re worth going through.

So this article is a summary of the concepts and approaches that Progressive Web Apps follow. I’ve written this from my experience building them, and I outlined this article after going through the Google Progressive Web Apps Training.

The training does a good job of explaining how everything works together, and also takes you straight into the code. Udacity’s Mobile Web Specialist course also could be of help here.

Why PWA?

Time spent by average users on Web vs Apps

The web is Operating System independent, is widely reachable, and is the biggest platform on the internet. Yet we see that users spend a lot more time on native apps than on the web.

Why is this so?

The main reason is the smooth experience and engagement native apps provide. How about we bring these features to Web Apps? That would mean the combination of the ease of access and reach of the Web (3x as compared to native apps), along with the immersive experience of native apps.

According to Alex Russell, who coined the term, PWAs are:

Just websites that took all the right vitamins

These vitamins are just features of native apps that we add on to Web Apps to get the best of both worlds. Apps that you can access directly from the Web, yet work smoothly and faster, are installable, and may even have notifications.

Comparing web, native and progressive web apps, from Google’s PWA training

What makes PWAs what they are

The key features according to Google:

  1. Reliable: Offline-first, meaning it should provide interfaces even in poor or no internet connection. But this also doesn’t mean that the app should just be able to work when offline, but rather provides undisrupted service in all network conditions.
  2. Fast: Instant-loading, and smooth experiences even on loading content.
  3. Engaging: Should provide an immersive experience, equivalent to that of a native app. Can have Push notifications, Web Payments, or Credential management and so on. Being installable is also a key feature here.

But these are just concepts — how do we think about implementation from a technical point of view? Samsung Internet’s Peter O’Shaughnessy has a good approach for this:

PWA Standards

So let’s get into these one by one:

Service Worker

It’s a JavaScript file that runs separately from the main browser thread in the background, intercepting network requests, caching resources, and providing a base for multiple APIs including push notifications, background sync, and caching.

Flow diagram for Service Workers intercepting network requests

The ability of service workers to run separately in the background helps give a lot of functionality to the app even when closed, providing a more native app-like and engaging experience.

It also helps in making the app offline-first as it acts a proxy between the server and application.

An introduction to service workers can be found here, and Google has a few helpers open sourced in their Service Worker Toolbox.

HTTPS

Hypertext Transfer Protocol Secure is an adaptation for secure HTTP communications using SSL or TLS encryption. But let’s not get into that — rather, we’ll go into the reason why it’s important.

Other than the fact that PWAs are expected to be highly secure, service workers that they use can intercept network requests and modify responses. This can be exploited easily to cause serious attacks. There are many services which help you get your site an SSL certificate like LetsEncrypt and SSLforfree.

Web App Manifest

Basically a JSON file that gives information about how the app should look in the home screen, on the web, and so on. It can be used to add a theme color, icons for the home screen, and a splash screen to name a few.

A simple manifest would look like this:

{
"name": "HackerWeb",
"short_name": "HackerWeb",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"description": "A simply readable Hacker News app.",
"icons": [{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}],
"related_applications": [{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
}]
}

It makes the app look more native-friendly with all the icons, themes, and splash screens. It’s installable with just a JSON file.

Read more about them in Mozilla’s Web Docs and generate one here.

For favicons of different sizes, you can generate them from a single high quality image by using Favicon-Generator and the theme. Background colors can be picked from the app’s palette.

Push Notifications and Background Sync

The server delivers push messages to the service workers, which intercept and update the local state or display a notification to the user. Since they run independently as a background process, this is possible even with the app closed. Push API could help you implement this functionality.

Background Sync API pushes periodic updates to the server so that the app can update when it’s online. Basically it makes sure all the messages are sent when there’s a good connection.

Additional Concepts

Below are few approaches and standards to follow while working on building Progressive Web Apps.

Lighthouse and PWA Checklist

Lighthouse audit taken for AliExpress PWA

Lighthouse is an automated tool for checking the quality of web pages by taking audits in performance, best practices, accessibility, SEO, and progressive web app standards. This is a good way to check if your app meets the standards and to see how good of a PWA it is.

You can figure out what your web app lacks and how it can be improved by using the suggestions from Lighthouse audits and also this PWA Checklist by Google which lays down all the general guidelines to follow, and how to fix issues. And the best part is, right now, Lighthouse comes built into Chrome DevTools!

Storage

According to Addy Osmani (on the Google Chrome team), the best practice for storage to be followed in PWAs is:

Use the Cache API for URL addressable resources (part of Service Worker). For all other data, use IndexedDB (with a Promises wrapper).

Both of these are asynchronous APIs which work with web/service workers. This makes them suitable for use with PWAs, unlike other methods such as localStorage.

For a quick idea of what IndexedDB you can refer to this resource.

Put simply, it’s a large scale noSQL storage system which can store about anything from the browser. It also works as a high performance API.

Caching

The Cache API which can be used in the Service Worker allows you store responses keyed by request. This allows content to be directly loaded from Cache in the event of a poor network and it can also be further configured to load only the necessary data while relying on the cache for everything else.

Example for app shell in Flipkart Lite PWA

One of the popular patterns for approaches for offline-first and native-app like experience is caching the application shell. This includes all the basic HTML, CSS, and JavaScript that make up the navigation/toolbars or whatever is common throughout the layout. So the app shell loads instantly and shows a loading screen as content is fetched, giving a streamlined experience.

Fetch and Promises

For fetching resources, the latest and recommended way is to use the Fetch API with Promises.

// A basic fetch example with promises
fetch(‘examples/example.json’)
.then(function(response) {
// Do stuff with the response
})
.catch(function(error) {
console.log(‘Looks like there was a problem: \n’, error);
});

XMLHttpRequest (XHR) requests are unnecessarily verbose and so are callbacks, which fragments code and causes confusion when long callback chains are used.

Promises are a better way of handling asynchronous code.

Service Workers, Cache API, and Network requests extensively use these for performing a variety of tasks and are required at base level, hence it’s very important have a proper idea about these.

Responsive Design

This not only means using responsive units of width. Content blocks should be manipulated for the needs of the layout. The app needs to look perfectly made for mobile, and overall it should look like a well-designed native app.

Steps for Manipulating content

Modern CSS layout systems such as CSS Grid (Learn with this free course by Wes Bos) or Flexbox can be of great help for managing different layouts and arrangements of different screen sizes.

Image Optimization

Data distribution in web apps

One of the key features of PWAs is that they should be blazing fast, and you can see that images aren’t helping. They need to be replaced with SVGs or removed wherever possible. Web optimized formats should only be used with the lowest size possible.

But it’s also important that these images be fluid and still go well with different screen sizes, as another import feature of PWAs is their native app-like experience.

Stories and Examples

A few real-world examples of PWAs

Conclusion

With every service launching an app, people often find it inconvenient to actually go to the store and download it. They hate spending that much time, mobile data, and space on the device. This often leads them to the web, which requires way less effort. But then, we see high bounce rates, because the web experience is not as smooth and optimal as the native app.

The solution for both of these problems is Progressive Web Apps, which combine the best of the two worlds, giving the optimal user experience.

As mentioned, with the support for PWAs increasing greatly in all platforms, now would be the best time to get started.

BookMyShow’s Progressive Web App drives an 80% increase in conversions

Building Flipkart Lite: A Progressive Web App

Great examples of progressive web apps in one room

Further Reading

Converting React apps to PWAs:

Converting Angular apps to PWAs:

Hope you enjoyed this article and found it to be a good read! You can check out all my projects on Github and don’t hesitate to reach out to me on Twitter!