Easier mobile development with PWAs

Nuria Extremadouro Mayoral
guidesmiths
Published in
6 min readNov 20, 2020

Having a mobile application can be advantageous for a business, but their development is not as easy as it seems. Or is it?

A Progressive Web App (PWA) is a web application that can be installed on a device in a similar way as a native app. However, there are some differences to take into account before deciding which one is best to use. Once we understand these differences, we’ll move onto their requirements and some sample code.

PWA vs Native

First of all, let’s make clear that both options have their advantages and disadvantages. This article will focus on PWAs, but that doesn’t mean they’re better in every aspect. So to make sure that a PWA will cover your needs, let’s look at what they can do.

Some of their strong points are:

  • Same code for web and mobile, making development and maintenance easier (and cheaper!). This also implies that there’s no need to learn specific languages or frameworks for each OS.
  • Having a native feel with offline behavior, responsive designs, push notifications and access to many other capabilities. For more information, you can check What PWA Can Do Today.
  • Since the installation can be prompted from your website, you’re not reliant on app stores, which can be very restrictive depending on what your business is about. You can still submit your app to them if you want to and there are tools such as PWABuilder to make the process easier.

And here are their main downsides:

  • PWAs have limited access to the hardware and software of the device, so they’re more limited than native apps. You will have to check that your app has access to everything it will need.
  • Apple is still reticent to fully support PWAs. Safari has some extra limitations for them. As a personal opinion, the current limitations from Safari can be gracefully handled. The App Store makes it harder to submit them (but still possible). I won’t cover here the specifics because as time passes, these blockers are slowly being removed.

Requirements

To turn a normal website into a PWA there are a list of minimum requirements that need to be met:

  • Have a valid manifest file. This will configure some of the basics of your app, such as the name, icons, etc.
  • Use a service worker. This script is a must to offer offline behavior, but it can also improve performance and handle other functionalities such as push notifications.
  • Serve your app through HTTPS. This is a requirement in order to use service workers, but it’s also a way to make your app secure.

But if we don’t want to stay on the bare minimum, here are more things to take into account:

  • Responsive design. Keep in mind that a PWA should feel like a native app on all device sizes and browsers. It should also work well with different input types (mouse, keyboard, touch, etc.).
  • Performance. Your app should load fast and reduce the number of resources fetched by caching what’s needed. This will also reduce battery consumption.
  • Make sure your app can be discovered through search engines. This is especially true if you don’t submit your app to any stores.

An easy way to check how your website meets these requirements is by using the tool Lighthouse. With it, you can get reports for various aspects and I will be using it for the hands-on sections below.

Let’s see some action!

For this example, I’m going to create a basic React app to showcase the previous requirements. You can find the repo here.

Many frameworks (React, Angular, Vue, etc.) already offer the option to have a basic setup to make your newly created app a PWA. This means our new React app already has some things configured. We’ll learn about these settings and how to fix the missing pieces.

Using Lighthouse

If you’re using Chrome, you can open the dev tools and switch to the “Lighthouse” tab. Click on “Generate report” to see what’s our starting point.

Lighthouse report

We’ll cover the different points and fix the missing requirements, but we’ll follow the order from the Requirements section for clarity.

The manifest file

By default, an app generated with the CRA has a basic manifest.json that can be found on the public folder. This file is already doing a lot of work for us:

  • It has the minimum fields and icon sizes (192x192 and 512x512) to meet the installability requirements.
  • A custom splash screen can be auto-generated thanks to the icons, background_color and name properties.
  • It sets a theme_color that matches the one from the index.html file.

The last missing point here is having a maskable icon, which can be easily fixed by adding “purpose”: “maskable” to any of the icons. And what are these maskable icons? They’re a new icon format that is much more adaptive and configurable when your app is installed.

Aside from that bare minimum, I would recommend having description, icons for different device sizes and both name and short_name. For a more complete list of properties, check this list. Our resulting manifest would be:

Setup a Service Worker

I’d say this is the more interesting part of setting up a PWA. A service worker is simply a script that allows us to control network requests, cache them and provide offline access with these cached resources.

We could use the default SW generated by the CRA, which internally uses Workbox. Instead, I’m going to create my own SW which I think will be more illustrative of how this works. We’ll do the following:

  • Create a registerSW.ts file on the src folder. This will check if SWs are supported, wait until the page is loaded, check the existence of a valid SW file and register it.
  • Create a service-worker.js on the public folder. This is the file that will control the lifecycle of the SW where we will cache our requests.
  • Modify the index.tsx file to register the SW.

Inside the src folder, add the following file:

Then, inside the public folder create the service-worker.js file. It needs to be here to be found when the registerSW.ts file attempts to register it:

Finally, modify the index.tsx file to register the SW:

Now, if we run our app and generate a Lighthouse report, we’ll see that two issues related to the offline behavior and the non-registered SW are gone. We’re almost there!

Use HTTPS

When you’re running on localhost, the Lighthouse report will say that the app is running over HTTPS. But once you deploy your website, this will no longer be the case unless you set it up correctly. It is outside the scope of this article to cover the details of certificate generation, so for our demo, we’ll be using Vercel to deploy our app.

Vercel is a service that handles all the deployment steps, including all the setup needed to use HTTPS and redirect HTTP traffic to it. It’s also very easy to use. Simply modify the settings of your repo to allow access for Vercel, go back to the Vercel site and import your repo there. Once it’s deployed, you will receive a link to your newly deployed app with no HTTPS-related issues. Finally!

All checks are met!

Finishing touches

Noticed that some things were magically fixed with the CRA? We’re covering those now, and all the magic is happening on the public/index.html file.

  • A couple of them are related to the viewport property. On the meta tags we set it to fill the whole screen to help make our app responsive.
  • Another one is to offer some content when JS is not available. For that we have the noscript tag.
  • The last one is about the apple-touch-icon which is simply linking one of our icons to serve as the icon used when the app is installed.

This is the final result:

With this, we have the basics of a PWA covered. Of course there’s a lot of room for improvement as this is just a simple example. We could improve the offline behavior, design our custom install experience, etc. but those things could take an article by themselves. Thanks for reading!

--

--