Maximiliano Firtman's articles, notes and learning experiences for devs-firt.dev

PWAs, Welcome to the mobile revolution

How to unite app and web design seamlessly together.

Maximiliano Firtman avatarby Maximiliano Firtman Twitter @firt About Newsletter

About 9 min reading time

PWAJust as Responsive Web Design closed the gap between desktop and mobile sites a few years ago, progressive web app techniques are currently closing the gap between the web and the app world. With user experiences from desktop to mobile apps rapidly converging, it seems as though a much sleeker, more efficient internet is evolving – although inevitably not without some significant changes to its underlying genetic code.

Evidently there are some significant selective pressures driving this. First of all, creating native apps for every niche isn't necessarily an efficient use of resources: users end up with hundreds of big apps wasting bandwidth and valuable disk space and companies spend a great deal of money creating apps only for them to be abandoned after their first versions. And most of these apps are just driven by web content: information coming from web services or a content management system.

The definition of a progressive web app is not concrete. A PWA is just a web app that uses several new APIs and abilities in the web platform using progressive enhancement to offer an app-like experience on every platform with the same code base. It's more a set of best practices and API usage that creates an excellent app-like experience for your users, so it's not like you have or don't have a PWA; it's more like your site is more or less PWA.

The ascent of PWAs #

PWAs on Desktop

With PWAs on desktop, responsive web design has a new meaning as we need to support really tiny viewports and offer a widget-based view of our content

While the name PWA was coined in 2015 in the article Escaping Tabs Without Losing our Soul by Alex Russell working at Google for the Chrome team, their journey didn't actually start there. We used to have HTML Applications (HTAs), which were created by Microsoft in 1999, along with many other web app platforms from Nokia, BlackBerry and other companies. Then, in 2007, Steve Jobs presented what was at the time the only way to create apps for the original iPhone: PWAs, albeit with a different name. Chrome started from there, improved the APIs a few years later and invented the PWA name.

With so many previous failed experiences trying to bring web content to the world of apps, why do we think it'll work now? Well primarily, it's down to the companies that are now working and promoting the technologies behind PWAs, such as Microsoft, Google, Apple and Mozilla, to name but a few. Also, the performance of the web platform reached a point where there is no perceived difference when you compare a well-designed PWA with a native app. Those conditions have never existed before and that's one reason the web community has decided that the time has come for PWAs.

PWAs in action today #

PWAs in Mobile

To provide a good user experience for your iOS users you must supply Apple-specific content

Today PWAs are fully functional and installable on:

  • Android with most browsers, with Chrome offering the best experience
  • iOS with Safari
  • Chromebooks
  • Windows 10 from the Microsoft Store
  • Feature phones with KaiOS – a fork from Firefox OS – currently available for millions of users mainly in India

Support is also coming to macOS, Windows and Linux through Chrome later this year. It's available today as an experimental flag 'Desktop PWA' if you want to try it now. Installation on  Windows on Edge without the usage of the store is coming later as well, although no specific time frame is defined.

If you reread the list, you can see every platform has or is about to have support for fully installable PWAs in the following months. And because a PWA is just a website with features on top that will be activated only on compatible browsers, we can even say it's compatible with all browsers from its basic functionality.

Also, PWAs are currently being generated from most of the CLIs for different frameworks, including the Angular 6+ CLI, React Create App, PWA Starter Kit from Polymer and Preact CLI. Finally, the Ionic Framework team came up with the idea of Capacitor, an open-source Cordova replacement that makes native PWAs possible on every app store.

Installation #

Progressive web apps: installation

On different browsers, the manual option to install a PWA's icon is different; on Windows 10, it's just an app in the store

One of the critical aspects of a PWA is the installation of the app. This process is done in two optional steps: the download and offline storage of the app's files and the icon installation in the OS. Because both steps are optional, you can offer an offline experience in the browser or you can offer an icon without offline installation. But a true PWA should include both: it must be served with TLS under HTTPS and the user will decide if they will use it in the browser or within its own installed icon.

Offline and immediate launch #

The brain of a PWA is the service worker, a JavaScript file installed on the user's device that is responsible for downloading the app's files, storing them into a cache and later serving them when needed. Once the service worker is installed, it acts like a network proxy for every resource that the web app needs: it can decide to fetch it from the network or deliver it from the local cache, which makes the app available offline and also available in just a couple of milliseconds even if the user has connection, emulating a native app launch.

In order to install a service worker, your HTML document will need to include something like:

if ('serviceWorker' in navigator) navigator.serviceWorker.register("sw.js");

That will install the file "sw.js" onto users' devices for the current folder in the current domain – a concept known as the scope. After it is installed, the next visits to any URL within its scope will be managed by that service worker.

Let's say we have a PWA with four files: index.html, app.js, app.css and logo.png. The first thing is to install those files into the cache in the sw.js file.

const resources = ["index.html", "app.js", "app.css", "logo.png"]; 
self. addEventListener("install", event => {
event.waitUntil(caches.open("myPWAcache")
.then( cache => cache.addAll(resources) )
);
});

Then for the PWA to be always served from the cache, we need to listen for the fetch event within the service worker and decide the cache policy to use, such as cache first with the following snippet.

    self.addEventListener("fetch", e => { 
e.respondWith(
caches.match(e.request).
then(res => res || fetch(e.request))
);
});

In this case, every time the user accesses the PWA (both from a browser or from an installed icon), the engine will get the files from the cache. An advantage of PWAs versus native apps is that devices needn't download all the files again when there's a change, only the file that has changed with a transparent process. Also, we can still download parts of the app on demand.

But the challenge is how do you know which files were updated on the server so you can replace them in the cache? If you don't want to write a low-level service worker to manage this, you can use the open-source library Workbox, which will help you with the generation of the service worker and the resources manifest to update the installed package.

Be aware that the files of your PWA will be deleted if there is storage pressure on the device, unless you request Persistent Storage if available:

if ('storage' in navigator && 'persist' in navigator.storage) 
navigator.storage.persist();

On Chrome and most Android browsers, your app isn't able to use more than five per cent of the available space; on iOS it's 50MiB (near 50MB) per host only; in Edge it's variable according to the total memory size and in Windows Store, it's unlimited.

First-class experience #

Progressive web apps: installation techniques

Different ways that browsers have to invite the user to install the PWA; on iOS you have to do it manually

We have the brain and now it's time for the heart: the web app manifest. The purpose of turning a website into a PWA is not just to ensure it is available quickly or while offline but also to enable it to have its own icon in the OS and offer an entirely standalone experience like any other installed app.

The manifest is a JSON file that defines metadata for the PWA used by a browser or an app store in order to define the installation behaviour.

The file defines several properties as metadata for your PWA. Each OS will read these properties and try its best to match the experience you prefer. For example, Android will read 'display: standalone' and create a normal app experience. With 'display: minimal-ui' it will create an experience with a visible URL and TLS certificate – useful for security-sensitive apps. With 'display: fullscreen' it creates fully immersive apps without status bar or visible back button. A set of icons and colours defines how the splash screens or title bars will look for your app's window.

There are some manifest generators, such as Web App Manifest Generator or PWA Builder that will also resize the icon for you in different resolutions if you provide a high resolution one (minimum 512 pixels).

When you have the manifest file linked in your HTML document, users will be able to install the app using different techniques depending on the browser, typically called Add to Home Screen, Install or just Add. If your PWA is crawlable by Bing, Microsoft will automatically add it to the Microsoft Store so Windows 10 users will be able to install it from there.

On some operating systems, your PWA will have the ability to capture links. This means that after the user has installed the app, any URL within the scope of your manifest will be opened within the boundaries of your app and not in the browser, no matter whether it appears in the browser or other apps such as WhatsApp, Facebook or an email.

If you pass the PWA requirements that we are defining here, some platforms will offer ambient badging (a small icon usually in the URL bar specifying that the web is installable) or a web app banner. If you prefer, you can also add your own custom Install button using the following snippet:

window.addEventListener("beforeinstallprompt", function(e) { 
e.prompt(); // will show installation native prompt
})

If the PWA is installed, the event 'appinstalled' will be fired on the window object so you can track stats listening for it.

App stores #

PWA Builder

PWA Builder is a free tool available from Microsoft that will help you in the creation or publishing of your PWA for different platforms online or in the command-line

One of the major benefits of installing from a browser is being able to avoid the app-store approval process or having to pay to be a publisher. That comes with obvious advantages, such as instant publishing, creating private apps for companies or apps that shouldn't be accepted in the stores.

But some companies do want to be in the store. As of today, the only stores officially accepting PWAs are the Windows Store and the kaiOS Store. Fortunately, with tools like Capacitor (currently in Alpha) or PWA Builder, we can create and sign native packages for other platforms as well.

There are some PWAs already published in the Google Play Store, such as Twitter Lite and Google Maps Go, currently under custom implementations. Chrome will offer a solution from Chrome 68 via trusted web activities. From that point, we will be able to create an Android package (APK) with a launcher to our PWA and upload it to the store. For the Microsoft Store on Windows 10, the site PWA Builder is currently helping with the generation of an APPX Windows 10 package. Using a web view, you might be able to manually create an iOS app for the App Store but be extremely careful about the store's rules.

Platform integration #

PWAs in Mobile

A basic PWA in action on different platforms; on macoS, it's still an experiment on Google Chrome

By implementing progressive enhancement techniques, you will be able to use many features, including push notifications, camera and microphone access, geolocation, sensors, payments, share dialogs and offline storage. All of these features run directly within the browser's security model, including permission dialogs.

We can also communicate with other apps through URI schemes, such as opening Twitter, YouTube or WhatsApp through their URLs or custom URIs, such as whatsapp://.

Finally, when creating native PWAs that are published to the store using Capacitor or to the Microsoft Store, we will be able to bridge to native APIs that will enable us to execute virtually any native code. That integration with Windows 10 includes hardware access but also integration with the OS, offering options such as Pin to Start. For example, the Twitter PWA lets you pin any user to your start screen.

Design and UX challenges #

PWA in Lighthouse

Lighthouse will give you a score stating how PWA your solution is based on a series of tests on a Chromium engine

Designing PWAs has unique challenges, so it's important to spend some time researching, testing as much as possible and considering the following:

  • Users will expect app-like experiences.
  • The installation process is still new, so we need to make extra effort to explain how to install the app.
  • Updating the app in the background without user interaction is great but it also adds some challenges for the UX.
  • On the desktop, responsive web design takes a new frontier as PWA windows can be tiny, much smaller than a mobile viewport. This means we need to create specific views or small widgets for this format, as seen in Chrome OS today.
  • Push notifications should add value to the user only, so learn to ask at the right moment and don't waste the opportunity sending messages that are not useful or interesting.
  • We need to design for web performance and for offline access.

The year of PWAs #

With the addition of iOS and desktop this year, PWAs are everywhere today. But we need to remember that their journey is just starting, so expect frequent changes and make sure to keep yourself updated with the latest techniques and ideas to deliver an excellent user experience while the platform evolves.

.net mag cover

This article was originally published in issue 308 of .NET Magazine

Half typewriter, half computer

© Maximiliano Firtman (@firt)

firt.dev contains a collection of writings, thoughts, notes and learning experiences for web and mobile app developers authored by Maximiliano Firtman.

Contact me: hi@firt.dev Personal Website Buy Me A Coffee