What is a Progressive Web App?

September 19th, 2016 / placed in Study. / Tags: , , , , .

Introduction about “Progressive Web App”

“Progressive Web App” is an umbrella term used to describe web experiences so advanced that they compete with the well known apps from the app stores. Progressive Web App will bring the features we expect from app-store apps to the mobile browser. On the whole, the term “Progressive Web App” describes a collection of technologies, design concepts, and Web APIs that work in tandem to provide an app-like experience on the mobile web.


Full offline support, install-ability, “Retina”, full-bleed imagery, fast, smooth in-app browsing, push notifications and a great user interface. Sound the the description of an app from the app-store, right? Well, all of these features can be provided by one single Progressive Web App.

“Progressive Web Applications are experiences that combine the best of the Web and native applications. They do not require installation. The user builds gradually a relationship with the application over time, it becomes increasingly more and more powerful. Load faster and send relevant notifications. Provide icons on the Home screen and immerse you in Full Screen mode.” (Google, 2015)

This way, in most use cases, you are good to go with developing a Progressive Web App instead of developing an native app. You get the features you want, and save a lot of money in development costs.

What does this definition pin point?

 –  There is no installation required.
 –  Icons on the Home Screen.
 –  Full screen capabilities (without the browser UI).


The definition above does not describe the entire nature of a Progressive Web App. There are a number of key attributes that are equally important. The list contains:

– Standard – uses the same platform and technology used to create web pages: HTML, CSS and Javascript.
– Progressive – It works for all users, regardless of browser or operating system used, because it is built to gradually improve from the beginning.
– Responsive – fits any screen resolution and format: desktop, mobile, tablet, TV or whatever.
– Independent connection – is enhanced with service workers to work offline or on slow networks with intermittent connections. (I’ll get to service workers in the next chapter).
– Works as a native app – the user will use it as an app , with support for navigation and interaction with gestures.
– Easy update – it will always be updated through automatic update process service worker.
– Secure – works on HTTPS to prevent someone from intercepting data and to ensure that the content has not been tampered with by others.
– Discoverable – it is identifiable as an “application” thanks to the manifesto of the W3C (W3, 2017) and registration of functions of service worker, allowing web searchers to find them.
– Interactive – it makes it easy to interact with it even when closed with features such as push notifications.
– Installable – allows users to create shortcuts on the screen of their phone for easy access.
– Linkable – can be shared easily using web address (URL) and does not require complex installation processes.

Research Goals

I want to know what makes a web app/website a “Progressive” web app, and if Progressive Web Apps could become an important technique/architectural approach for future development of web apps. Could the creation of a Progressive Web App be a final solution like “one app to rule them all”? I will also highlight some of the aspects of a service worker.

What is the “Progressive” part exactly?

Imagine waking up in the morning, and visiting the website of your local train company. You take out your phone, check out the schedule of the train that will take you to work, close your browser, and put the phone back in your pocket. At the end of that day, you visit the site again and check when the next train departs (not even noticing that the elevator you are riding has no cell reception, because the site now works even when you are offline because of the service). The next day when you visit the website again, your browser asks you if you would like to add a shortcut to the site on your home screen, and you happily agree. Later that day when you launch the site from an icon on your home screen, the site lets you know that due to some construction work delays may be possible, and asks you if you would like to receive notifications about delays on your commute. The next morning, as you are waking up, you receive a notification on your phone that your train has a 15 minute delay. You hit the snooze button on your alarm (Ater, 2017).

What started as a simple website, has slowly gained new powers until it was just as capable as any native app on your phone. Instead of trying to send you to the app store, hoping you will install their app, the train company has earned a permanent place on your phone, one step at a time. But what exactly provides these “progressive” powers to your web app?

Service Workers

From this part I am assuming the reader has basic knowledge about JavaScript.

“Rich offline experiences, periodic background syncs, push notifications—functionality that would normally require a native application—are coming to the web. Service workers provide the technical foundation that all these features rely on.” (Gaunt, 2016)

As described in the previous part about what the “Progressive” part is, the web app figured out you were a returning visitor. You haven’t even noticed there was no cell reception in the elevator, but the website somehow did still work. It asks you if you’d like to receive notifications and you even receive notifications. The service worker is responsible for all this.

What is a Service Worker?

A service worker is a script that your browser runs in the background, separate from a web page. It opens the door to features that don’t need a web page or user interaction.

One of the reasons why service workers are very powerful is that it gives you the ability to intercept and handle network requests. This is a very exciting feature because this way you are able to create offline experiences, gives developers full control over the experience. Sounds familiar? Correct! Before the service worker there was another API that gave users an offline experience on the web called AppCache. But according to Jake Archibald, there are a number of gotcha’s with AppCache that exist as well as the fact that while the design works particularly well for single page web apps, it’s not so good with multi-page sites. Service workers have been designed to avoid these common pain points (Archibald, 2013).

Before I go into a schematic, there are a few important things to know about service workers:
 –  Basically, it’s a JavaScript Worker. Meaning, it can’t access the DOM directly. Instead, a service worker can communicate with the pages it controls by responding to messages sent via the postMessage interface, and those pages can manipulate the DOM if needed.
 –  Service worker is a programmable network proxy, allowing you to control how network requests from your page are handled.
 –  Service workers make extensive user of Promises.


Below is a simplified schematic of a service worker on its first installation. I’ll go through each of these steps:

Progressive Web App - Service Worker Schematic

Figure 1. Service Worker Schematic (Google, 2016).

This stage marks the beginning of registration. It’s intended to allow to set up worker-specific resources such as offline caches. Here the install event is being fired.
– Use event.waitUntil() passing a promise to extend the installing stage until the promise is resolved.
– Use self.skipWaiting() anytime before activation to skip installed stage and directly jump to activating stage without waiting for currently controlled clients to close.

The service worker has finished its setup and it’s waiting for clients using other service workers to be closed.

There are no clients controlled by other workers. This stage is intended to allow the worker to finish the setup or clean other worker’s related resources like removing old caches. At this point the activate event is being executed.
– Use event.waitUntil() passing a promise to extend the activating stage until the promise is resolved.
– Use self.clients.claim() in the activate handler to start controlling all open clients without reloading them.

The service worker can now handle functional events.

The service worker is now idle and waiting to either receive a functional event like fetch, sync or push. In this state it can also be terminated and/or replaced by a new service worker.

Registering a Service Worker in your app

When we want to integrate a service worker inside an app we do it by registering it in your main.js or app.js JavaScript file. This is the entry point into using service workers.

 –  The outer block performs a feature detection test to make sure service workers are supported before trying to register one.
 –  Next, we use the ServiceWorkerContainer.register() function to register the service worker for this site, which is just a JavaScript file residing inside our app (note this is the file’s URL relative to the origin, not the JS file that references it.)
 –  The scope parameter is optional, and can be used to specify the subset of your content that you want the service worker to control. In this case, we have specified ‘/sw-test/‘, which means all content under the app’s origin. If you leave it out, it will default to this value anyway, but we specified it here for illustration purposes.
 –  The .then() promise function is used to chain a success case onto our promise structure. When the promise resolves successfully, the code inside it executes.
 –  Finally, we chain a .catch() function onto the end that will run if the promise is rejected.

The above will register a service worker. A single service worker can control many pages. Each time a page within your scope is loaded, the service worker is installed against that page and operates on it.

Install and activate

As we have seen in the schematic, and after we registered our service worker, the browser will attempt to install and then active the service worker for your site on its first load.

The install event is the place where you’d want to cache the looks of your app so the app can be used with it’s offline capabilities. This is done through the service worker’s storage API cache. This API works in a similar way to the browser’s standard cache, but it is specific to your domain. It persists until you tell it not to. Although this API is not compatible in every browser you can use IndexedDB instead.

 –  Here we add an install event listener to the service worker (hence this), and then chain a .waitUntil() method onto the event. This ensures that the service worker will not install until the code inside waitUntil() has successfully occurred.
 –  Inside waitUntil() we use the method to create a new cache called v1, which will be version 1 of our site resources cache. This returns a promise for a created cache; once resolved, we then call a function that calls addAll() on the created cache, which for its parameter takes an array of origin-relative URLs to all the resources you want to cache. This should be mainly contain your application interface elements.
 –  If the promise is rejected, the install fails, and the worker won’t do anything. This is ok, as you can fix your code and then try again the next time registration occurs.
 –  After a successful installation, the service worker activates.


Now we basically have a cached version we can serve once there is no internet connection. When the user navigates to a different page or refreshes, the service worker will begin to receive fetch events, an example of which is below.

Here we’ve defined our fetch event and within event.respondWith(), we pass in a promise from caches.match(). This method looks at the request and finds any cached results from any of the caches your service worker created.

If we have a matching response, we return the cached value, otherwise we return the result of a call to fetch, which will make a network request and return the data if anything can be retrieved from the network.

As I mentioned in my research goals I wanted to highlight some aspects of a service worker. The registration and install are the first steps you can do to get your Progressive Web App going. But, there is a lot more to discover such as prompting an install banner on your page, background synchronization or sending push notifications.


With the use of service workers inside a web app, it progressively enhances the experience for the user. You can cache your application and once the user has bad or no internet at all, they are still able to browse the application. And that’s only one of the many great features you can deliver without developing a native application!

Building a Progressive Web App is the way to go!

So, why should developers build Progressive Web Apps instead of native apps? Nowadays, Progressive Web Apps are gaining more terrain since users are downloading less and less apps (Tweedie, 2014) from the provided app stores. They are also gaining support for native features like push notifications, working offline, adding an icon to the home screen, launching in fullscreen, clipboard access and hardware accelerated 2D and 3D graphics using CSS3, HTML5 Canvas or WebGL. For a long time these kind of features were only available for native applications. Despite these rapidly evolving capabilities for Progressive Web Apps, there are still thing’s you can’t do (yet). For example accessing contacts, calendar and browser bookmarks, alarms and low-level access to some hardware features like the device’s flashlight.

But then again, the distribution of an Progressive Web App is much easier. If your app is online, it’s accessible for any mobile device without to need to go to the app store, search for the app, and download the app. With traditional native apps you need to develop for iOS, Android ánd a website. Not to mention you need to keep them all in sync and up to date. So for most cases, building an Progressive Web App is kind of an no-brainer. Then, if there is still need for an native application, you can still invest and develop one.

So, instead of building desktop/mobile web + native Android + native iOS you can now build Progressive Web App + native iOS. And once Safari has support for service workers it will be just Progressive Web App.


A list of references can be found here.