Progressive Web Apps the Right Way

By Cody Arsenault
Updated on September 8, 2022
Progressive Web Apps the Right Way

Since progressive web apps were introduced by Google back in 2015, they have been setting new standards for user experiences. While we are awaiting broader browser support, all developers should start learning how to take advantage of this exciting new way of building apps.

In this post, we'll go everything you need to know about progressive web apps including how to make one.

What is a progressive web app?

The term "progressive" applies not to what an app does but how it's made. Progressive web application techniques utilize the best aspects of traditional web pages and newer mobile apps to create unique user experiences. The idea is to streamline development utilizing multiple technologies to produce websites that look and behave like mobile apps.

Source: Google

The benefits of going progressive to users

According to marketing research, apps lose about 20 percent of users for each step between the first contact and actually being able to use the app. Before they even get to the installation phase, users have to go to the app store and wait for the app to download. Progressive web techniques allow users to skip some steps; users can engage with apps immediately on first contact, and then they are prompted to install the full-screen experience if they later reopen the app.

Native apps are not yet obsolete. Standalone mobile apps consume less data and may run faster than progressive web apps since more resources reside on the user's device. Nonetheless, progressive web applications boost retention rates and are easier to maintain than regular mobile apps.

The benefits of going progressive to developers

Having a web ecosystem that includes plugins and community support makes deploying and maintaining websites easier for learning developers, and it frees up time and energy for advanced developers to push their creative limits. Thanks to upgrades in browser capabilities, developers and users can now install apps to their home screens and work offline.

Developers who work on both mobile and web apps will appreciate that it's no longer necessary to maintain an API with backwards-compatibility.

Websites vs native apps vs progressive apps

Whether your next project should be a progressive web app, a website or a native mobile application depends on your intended audience. Since progressive apps run in web browsers, the user experience can improve with each browser update; however, progressive apps are not yet compatible with certain browsers like Safari.

Also, if you want to support functions offline, you'll have to figure out how to facilitate navigation without a back button. If critical user actions depend on features that are not available in all browsers, then you should make a native mobile application to ensure a consistent experience. If you have a website that already has an app-like interface, it should be easy to apply progressive web techniques to improve the user experience.

What makes web apps progressive?

Progressive web apps allow users to continue using certain features even while offline. Progressive web apps can be defined by the following additional characteristics:

  • Progressive apps work on any device by utilizing features on the user's hard drive and browser.
  • Progressive apps are more search-engine-friendly than native apps, so they are easier for users to discover.
  • Progressive apps retain or reload their state when users bookmark or share URLs.
  • Progressive apps have responsive interfaces that adapt to any screen size.
  • Progressive apps are usually built on the application shell model with the goal of minimizing page refreshes.
  • Progressive apps can keep working with low or no connectivity. Newly published content gets loaded when the user reconnects.
  • Progressive apps can re-engage users with web push notifications.
  • Progressive apps are easily installed on the device's home screen.
  • Progressive apps should be hosted over HTTPS to ensure security.

In a progressive app, the user interface is an application shell that is separate from the dynamic content. This architecture allows browsers to cache the application shell and continue working offline even if the app was recently closed. Repeat visitors will see faster load times since the resources are cached.

How to make a progressive web app

You can follow the instructions below to take an existing app, which was built using Vaadin Elements and Polymer, and start turning it into a progressive web app. We'll use an example boilerplate template provided by Vaadin for an app that tracks a fictional sales teams' progress by individual employee. You can see an explanation of the template here, but you don't actually need to understand how the app works to follow this tutorial.

Step 1: Pick a boilerplate template

Once you have the Vaadin framework up and running, we'll begin by installing the Polymer CLI tool.

npm install -g polymer-cli generator-polymer-init-vaadin-elements-app

Next, you'll need to create a directory for your project and cd into that directory. We're also going to install the Vaadin Elements generator, which will allow us to build an app that we can modify to add offline support.

mkdir your-project
cd your-project
polymer init vaadin-elements-app

Serve the app with the Polymer CLI to run it:

polymer serve --open

Your app should now be fully functional and accessible via http://localhost:8080/your-project, but it will cease working if you go offline.

Step 2: Add an app shell

Users expect to see something right away when they click on your app, which is why you should always serve up an app shell before the rest of your data finishes loading. The app shell model ensures that your app keeps looking like an app even without an internet connection. The Google Developers website has a thorough explanation of app shell architecture. Since our example app has already been set up as an app shell, we can skip this step.

Step 3: Set up a service worker

Service workers provide offline support capabilities by caching resources so that the app can be displayed when network connectivity is unavailable. They are programmable proxies that run separately from your code. In addition to making your app internet independent, service workers also allow faster startup and background sync. We'll need one to make our example app progressive.

You can get more in-depth information about service workers from the Google Developers website. This diagram depicts the relationship between service workers and apps:

Source: Vaadin

Our example app is set up for service worker support; however, if you go into the project directory and inspect the service-worker.js, it reads:

console.info('Service workers will be generated at build time.');

Therefore, we must first use Polymer to build the app. To do this, run:

$ polymer build

You should now have two build folders: an unbundled one optimized for HTTP/2 and a bundled one that packs all of your assets into a few files. If you take a look in the build/unbundled folder and inspect the service-worker.js, you should now see a lot of data where there was none before. Your service worker is now set up to serve your application's shell. Now, serve the app with the following code:

$ polymer serve build/bundled

If you go offline and refresh your browser, the app shell should still load. This is a good start, but you need to implement caching to serve data.

Step 4: Enable caching and offline support

We will now make our app serve up the latest cached version of employee data so that users can continue viewing it offline. The next time the user connects to the internet, the cache will be replaced with the most up to date data. To do this, we can use a tool called sw-precache to scan your project files and cache resources that you specify in a config file.

Open sw-precache-config.js and replace the existing code with the following:

module.exports = {
    staticFileGlobs: [
        '/index.html',
        '/manifest.json',
        '/bower_components/webcomponentsjs/webcomponents-lite.min.js'
    ],
    runtimeCaching: [{
        urlPattern: /^http://localhost.*json/,
        handler: 'networkFirst'
    }],
    navigateFallback: '/index.html'
};

The staticFileGlobs block indicates three static files for the service worker to cache. These make up your application shell, which will always look and load the same. The runtimeCaching section specifies which files get cached when they are loaded into the app. The urlPattern expression is for matching json files. The handler tells the service worker how to handle requests.

The networkFirst handler makes the service worker first try to obtain the latest version of a json file from the network when requested. If the network request fails, the cached copy is displayed.

Step 5: Rebuild and go offline

You must now rebuild the app to implement runtime caching. While you're still connected to the internet, clear the build directory and run:

$ polymer build
$ polymer serve build/bundled

You must now refresh the app twice. The first refresh is to allow the service worker to see the application. During the second refresh, the service worker will cache the latest version of the specified json files.

At last, you can disconnect from the internet and refresh one more time. Rather than the offline dinosaur, you should now see the employee data loaded. You have a web app that is on its way to being progressive.

Tips for making progressive web apps

  1. When designing progressive web apps, you should prioritize using web technologies that are supported on the most browsers.
  2. The applications tab in Chrome DevTools contains some helpful options when making progressive apps. It lets you toggle the network, inspect service workers and view caches.
  3. Google has also put together an impressive checklist for making progressive web apps.
  4. Due to security vulnerabilities, progressive apps should always be served through an HTTPS connection.
  5. CSS libraries and frameworks like Bootstrap can help with responsiveness issues like typography and forming grids.
  6. Adding a web manifest allows progressive apps to be installed on the user's home screen among other things to improve discoverability. The Mozilla Developers Network has a detailed explanation of how to deploy a manifest. Although Safari doesn't yet support this feature, you can define app-like behavior using the following Apple-specific meta tag: <meta name="apple-mobile-web-app-capable" content="yes">
  7. Take advantage of the Push API to send out push notifications, which can drastically increase your user retention.
  8. Because the browser address bar and menus aren't visible in standalone mode, make sure to include in-app share buttons.
  9. Although anyone can manually add your app to their home screen by using a button in the Chrome browser menu, many users do not know about this option. Fortunately, there is an installation pop-up that prompts users to save the app; however, to prevent the abuse of pop-ups, Google has made it so that three conditions must be met before such prompts can be displayed:
    1. There must be a valid web manifest.
    2. There must be a valid service worker installed.
    3. The app must be served over HTTPS.

The future of progressive apps

Since progressive web apps rely heavily on web browsers, their future depends on broader browser support. As of now, only Chrome supports all of the available features. Opera, Mozilla, and Edge currently offer limited support, yet Safari provides no support at all.

Given their popularity, it's only a matter of time before progressive web apps become the norm. Until then, developers must keep finding ways to accommodate users who access their content in many different ways.

  • Share

Supercharge your content delivery 🚀

Try KeyCDN with a free 14 day trial, no credit card required.

Get started

Comments

Comment policy: Comments are welcomed and encouraged. However, all comments are manually moderated and those deemed to be spam or solely promotional in nature will be deleted.
  • **bold**
  • `code`
  • ```block```
KeyCDN uses cookies to make its website easier to use. Learn more