A progressive introduction to Progressive Web Apps
Guest post by Ian Naylor, Founder and CEO of AppInstitute, one of the world’s leading DIY app builders
The term Progressive Web App (PWA) only entered the lexicon of developers two years ago, and in the last few months it has seen more common usage. Like responsive design before it, there is a risk of it being used so frequently that people become blind to it. But like responsive design, PWAs are not a meaningless buzzword or temporary fad.
For those not already familiar with PWAs, a Progressive Web App is not actually an app. Like a responsive website, PWAs are – on the surface – ordinary websites with the ability to behave differently when viewed on a mobile device. Like responsive websites, PWAs start out as a browser tab on mobile devices, but if accessed frequently, users can be prompted to add it to their home screen or app launcher. And this is where the progressive part comes into play, once a user adds it to their home screen, the website begins to progressively look and behave like a native app.
What Are the Characteristics of a Progressive Web App?
Frances Berriman and Alex Russell, the original proponents of PWAs, compiled their own list of characteristics that a PWA should include:
- Responsive: Must display properly regardless of device.
- Connectivity Independent: Must be progressively-enhanced through the use of Service Workers, allowing them to work offline.
- App-like-interactions: Should adopt a Shell + Content application model to create app-like navigations and interactions.
- Fresh: They should always be up-to-date because of the Service Worker update process.
- Safe: They must be served via TLS to prevent snooping. This is a strict requirement for the use of Service Workers.
- Discoverable: They should be identifiable as “applications” through the inclusion of W3C Manifests and the Service Worker registration scope, allowing search engines to find them.
- Re-engageable: They should promote re-engagement through the use of push notifications, etc.
- Installable: Browser-provided prompts should encourage users to add them to the home screen, allowing users to “keep” apps they find most useful without the need for an app store.
- Linkable: They should be zero-friction, zero-install, and easy to share. The social power of URLs matters.
Google, who through Android and Chrome are strong promoters of Progressive Web Apps, distilled these characteristics into a checklist of things a PWA needs to do, or include. At a minimum, a PWA would need to tick all the baseline checks, but it is possible to improve the user-experience by also meeting the standards for an exemplary PWA.
Why and When to Build a Progressive Web App
As a developer you have access to the latest technology, including high-end smartphones, the latest operating systems, and high-speed internet access. It is always tempting to update your app to use the latest features of new smartphones and operating systems, but in doing so, you also risk having to bid farewell to some of your users. We easily forget that not everyone can afford – or has a need for – high-end smartphones. And there are many people who don’t replace their phone every one to two years. So a big part of the “why and when” of building a PWA is knowing the devices your audience uses. Another part is understanding the benefits – and limits – of PWAs, and how this relates to what you want users to do with your app.
Potential Benefits of a Progressive Web App
- Less friction than a native app. No need to first find it in the app store (and install it) before starting to use it.
- Works on any device with a browser installed. Although the true app-like experience is only available through supported browsers, the PWA will still function even with older browsers and operating systems. Progressive enhancements mean the experience improves on newer browsers, but isn’t dependent on them.
- Fast first-load and response times, along with the ability to allow some functions to work even when offline, make PWAs highly suited to businesses serving an audience with limited internet access.
- They don’t need a lot of space, and they use very little data compared to native apps.
Progressive Web App Limitations
- Limited access to system features. If your app requires access to certain system features to function properly, you’ll be better off going the native app route. PWAs have access to the same system features that browsers can access.
- Features such as the ability to easily add the “app” to the home screen, work offline, and even push notifications, are not available on iOS. Support for Service Workers is now under consideration for Safari, but that is only one aspect of PWAs. Using Chrome on iOS will offer a better experience, but it still won’t have access to certain features.
- There is a small risk of being ‘invisible’ to some users by not being listed in an app store. Although you are now visible to search engines, some users only search the app store when looking for certain services.
Some Asian and African brands have been quick to launch PWAs, while simultaneously highlighting that trying to be accessible to as large an audience as possible isn’t an ‘either-or’ dilemma. Jumia, Wego, MakeMyTrip, AliExpress, and Flipkart all have native mobile apps in addition to having a PWA. The native app serves the segment of their audience with access to reliable internet, and those who are using mid to top-tier smartphones. The PWA, on the other hand, is perfect for users with spotty internet access, and basic, entry-level smartphones. The results for all these brands more than justify the decision to rapidly deploy a Progressive Web App:
- Wego reduced page load speed from 12s to 1s. Organic visits grew by 12 percent, while bounce rates dropped by 20 percent.
- MakeMyTrip cut page load speeds by 38 percent, while tripling conversion rates.
- AliExpress managed to increase conversions by 104 percent, and even though Safari doesn’t fully support PWAs, the improved user experience translated to an 82 percent growth in conversions in Safari.
- Flipkart saw time spent on their website triple among users of their PWA versus the previous mobile experience, with users also benefiting from an ‘app’ where data usage was three times less than on the native app.
- Jumia’s PWA uses five times less data than the native app, leading to twelves times as many users than the native app.
Creating a Progressive Web App
The scope of this article is too broad to also include a step-by-step guide to creating a PWA, not to mention the many routes you could follow when developing a PWA.
PWAs are not dependant on a JavaScript Framework, but if you (or your team) are familiar with AngularJS, React, Preact, or Vue, you could speed up development by using any of them. Additionally, Google’s Polymer Project (now on version 2.0) is a library of web components heavily biased towards PWAs, and such as YouTube Gaming, EA, IBM, and Net-a-Porter are already using them.
PWAs depend on the W3C Web App Manifest, and Service Workers.
Web App Manifest Basics
The web app manifest is a fairly simple JSON file that makes your web app more app-like. The manifest makes it possible for your PWA to run as a standalone app in full-screen mode while also allowing you to assign a theme and background color, and to specify the icon to use if the app is added to the home screen or app launcher. Chrome on Android also looks for a manifest file in order to display the Add To Home Screen button and prompt. Common specifications of the manifest.json file are:
- short_name Provides a short human-readable name for the application. This is intended for use where there is insufficient space to display the full name of the web application.
- name Provides a human-readable name for the application as it should be displayed to the user, for example among a list of other applications or as a label for an icon.
- description Provides a general description of what the web application does.
- icons Specifies an array of image objects that can serve as application icons in various contexts. For example, you can use an icon to represent the web application amongst a list of other applications, or to integrate the web application with an OS’s task switcher and/or system preferences.
- start_url Specifies the URL that loads when a user launches the application from a device. If given as a relative URL, the base URL will be the URL of the manifest.
- display Defines the developer’s preferred display mode for the web application. Values include fullscreen, standalone, minimal-ui, and browser.
- orientation Defines the default orientation for all the web application’s top level browsing contexts.
- theme_color Defines the default theme color for an application. This sometimes affects how the OS displays the application (e.g., on Android’s task switcher, the theme color surrounds the application).
- background_color Defines the expected background color for the web application. This value repeats what is already available in the application stylesheet, but browser can used it to draw the background color of a web application when the manifest is available before the stylesheet loads. This creates a smooth transition between launching the web application and loading the application’s content.
- related_applications Specifies an array of “application objects” representing native applications that are installable by, or accessible to, the underlying platform — for example, a native Android application obtainable through the Google Play Store. Such applications are intended to be alternatives to the web application that provide similar or equivalent functionality — like the native app version of the web app.
Visit the Mozilla Developers Network to see a full list of specifications and possible values. Linking to the manifest.json file is as simple as adding the following code to the index.html file’s head tag:
<link rel=”manifest” href=”./manifest.json”>
An example of what the manifest.json file looks like:
{ "background_color":"#ffffff", "description":"It's what's happening. From breaking news and entertainment, sports and politics, to big events and everyday interests.", "display":"standalone", "gcm_sender_id":"49625052041", "gcm_user_visible_only":true, "icons":[ { "src":"https://abs-0.twimg.com/responsive-web/web/ltr/icon-default.882fa4ccf6539401.png", "sizes":"192x192", "type":"image/png" } ], "name":"Twitter Lite", "orientation":"portrait", "share_target":{ "url_template":"compose/tweet?title={title}&text={text}&url={url}" }, "short_name":"Twitter Lite", "start_url":"/", "theme_color":"#ffffff" }
Note that Chrome will only display the Add To Home Screen prompt and button if the following criteria are met:
- Your PWA must have a valid web app manifest file.
- Your PWA must be served over HTTPS.
- Your PWA must have a valid Service Worker registered.
- A user must have visited your PWA twice, with at least five minutes passing between each visit.
Service Workers Basics
The Service Worker is a simple piece of JavaScript, with a lot of power. It runs in the background, separate from your web page, giving your PWA access to features without requiring user interaction. The Service Worker makes it possible for users to open your PWA – even when offline – by caching static resources. Once the user reconnects to the internet, the Service Worker manages background sync, along with push notifications. In the future, Service Workers could also bring features like geofencing to PWAs.
The first step is to let the browser know that your site uses a Service Worker by registering it. You do this by adding the following code to your site’s main script file:
function registerServiceWorker() { // register sw script in supporting browsers if ('serviceWorker' in navigator) { navigator.serviceWorker.register('sw.js', { scope: '/' }).then(() => { console.log('Service Worker registered successfully.'); }).catch(error => { console.log('Service Worker registration failed:', error); }); } }
Ideally sw.js will be located in the root directory of your PWA which, as noted earlier, must be served via HTTPS. A basic sw.js file will look something like this:
/* Copyright 2016 Google Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Names of the two caches used in this version of the service worker. // Change to v2, etc. when you update any of the local resources, which will // in turn trigger the install event again. const PRECACHE = 'precache-v1'; const RUNTIME = 'runtime'; // A list of local resources we always want to be cached. const PRECACHE_URLS = [ 'index.html', './', // Alias for index.html 'styles.css', '../../styles/main.css', 'demo.js' ]; // The install handler takes care of precaching the resources we always need. self.addEventListener('install', event => { event.waitUntil( caches.open(PRECACHE) .then(cache => cache.addAll(PRECACHE_URLS)) .then(self.skipWaiting()) ); }); // The activate handler takes care of cleaning up old caches. self.addEventListener('activate', event => { const currentCaches = [PRECACHE, RUNTIME]; event.waitUntil( caches.keys().then(cacheNames => { return cacheNames.filter(cacheName => !currentCaches.includes(cacheName)); }).then(cachesToDelete => { return Promise.all(cachesToDelete.map(cacheToDelete => { return caches.delete(cacheToDelete); })); }).then(() => self.clients.claim()) ); }); // The fetch handler serves responses for same-origin resources from a cache. // If no response is found, it populates the runtime cache with the response // from the network before returning it to the page. self.addEventListener('fetch', event => { // Skip cross-origin requests, like those for Google Analytics. if (event.request.url.startsWith(self.location.origin)) { event.respondWith( caches.match(event.request).then(cachedResponse => { if (cachedResponse) { return cachedResponse; } return caches.open(RUNTIME).then(cache => { return fetch(event.request).then(response => { // Put a copy of the response in the runtime cache. return cache.put(event.request, response.clone()).then(() => { return response; }); }); }); }) ); } });
In this example, we are only caching index.html, some CSS, and demo.js, but you will decide what assets to cache when developing your own PWA. There is considerably more you can get your Service Worker to do, and Jake Archibald maintains an excellent set of resources relating to Service Workers.
Further Reading on Progressive Web Apps
I’m with Google in believing that Progressive Web Apps hold a lot of promise for a mobile experience that is accessible for everyone, regardless of internet speed, or smartphone feature set. And even if users aren’t too aware of what a PWA is, there are already plenty of resources available for developers looking to learn more about PWAs:
- Google’s own repository of information, tools, and case studies relating to Progressive Web Apps.
- Google’s Intro to Progressive Web Apps course at Udacity.
- Yes, That Web Project Should Be a PWA by Aaron Gustafson.
- Progressive Web Apps using the Angular Service Worker, a working document by Maxim Salnikov.
- A Progressive Web Application using Vue JS, Webpack and Material Design.
- Five tools for building Progressive Web Apps fast.
- Workbox, JavaScript libraries for Progressive Web Apps.
And if you’ve already developed and launched your own PWA, share your story (and URL) in the comments below.
About the Author
Ian Naylor is the founder and CEO of AppInstitute, one of the world’s leading DIY App Builders (over 70,000 apps built).
Naylor has founded, grown and sold 4 successful internet and technology companies during the past 18 years around the world. He gives seminars as an expert authority on startup mobile app trends, development, and online marketing and has spoken at numerous industry events including The Great British Business Show, Venturefest, the National Achievers Congress and numerous industry exhibitions around the UK.
AppInstitute regularly provides leading publications with app analytics, business data, case studies, white papers and statistics for established publishers across the world. They were named in the top 50 creative companies in England by Creative England.