Progressive Web Apps: A Guide

Progressive Web Apps: A Guide

Hello there👋

Today we will be diving into the world of Progressive Web Apps, often referred to as PWAs. By the end of this article, you should know what a PWA is, how it works, its benefits and drawbacks and how to create one with React. Let's get right into it!

What is a PWA?

A Progressive Web App, or PWA, is simply an app with the look, feel and functionality of a native app. Native apps are applications that are built for a specific operating system, like iOS or Android, with a specific programming language.

How does it work?

Here are the components required to build a PWA:

HTTPS: PWAs are served over HTTPS, providing a secure connection between the user's device and the server. Service workers require HTTPS. If your production web server does not support HTTPS, then the service worker registration will fail.

Web App Manifest: This is a JSON file named manifest.json. It provides information (metadata) about the app, such as its name, icons, theme and background colors, name, description and more. This metadata will still be included and used regardless of whether or not you opt-in to service worker registration.

App Shell Architecture: This is a design pattern that involves separating the core application structure (the shell) from the dynamic content. The shell is loaded first and provides the basic user interface, while dynamic content is loaded later.

Service worker: Service workers provide offline functionality to websites. They enable;

  • fast loading (regardless of the network)

  • offline access

  • push notifications

  • improved performance and reduced server load due to its Cache index

  • background synchronization whereby tasks are performed in the background even when the web page is not open e.g. fetch requests.

To view a list of active service workers, enter chrome://serviceworker-internals into your address bar.

What are the features of a PWA?

  • Installable: A common feature of PWAs is that they can be installed on your device, just like a native app. However, compared to a native app, they are fast and lightweight.

  • App-like Experience: A PWA should be similar to a native app. It should include things like app icons, splash screens etc. It should also be responsive and usable at any screen size as PWAs also cater to mobile users. On mobile devices, users can add the PWA to their home screen. They would be able to access the app by clicking on the app icon (provided by manifest.json) on their home screen.

  • Offline Access: Users tend to interact more with an application that is readily available and accessible, regardless of network state. PWAs allow offline access, similar to native apps. Users can access some pages on a PWA, due to its caching ability, instead of being shown only a "network error" page. You may choose to make users aware of the fact they are offline or have bad network connectivity, especially in a case where they need to view live data.

Benefits

Cost Efficient: Native apps are designed and built for a particular operating system (OS) or platform. They are developed using programming languages and tools that are native to that platform. This means that a native app for Android is written in a different programming language (Kotlin) than a native app for iOS (Swift). This development requires separate codebases for the different OS types which can increase development costs. For instance, you may have to learn a different programming language or hire two developers. This may also increase timeframes as compared to PWAs which save time because you would not be writing from scratch as you have only one codebase, you will only be configuring your current website to fit.

Safe: PWAs are served over HTTPS. It is a requirement for production deployments. If your production web server does not support HTTPS, then the service worker registration will fail as it is only enabled in a production environment.

Lower Barrier to Entry: Users don't need to go through the process of downloading and installing an app from an app store. They can simply access the PWA through a web browser, reducing the friction to start using the app. It is also an alternative option for users who do not want to have to type in or search for your website on a search engine before using your services and may not also want to download a mobile app that may take up resources on their device.

Maintainable: Maintainance and consistent updates of native apps require more money and time as compared to PWAs. They are app store independent. You do not need to visit an app store for an update. PWAs are web-based and any updates made to the website are reflected in it.

Cross-platform: They can work on multiple platforms and any device with a modern web browser. When building an app, best practices for responsive design should be employed so apps are responsive and work with different screen sizes.

Discoverable: In terms of search engine optimization, PWAs are easily discoverable as they are converted websites. As long as the website is search engine optimized, there is a higher chance of being crawled and indexed by search engines, and consequently, generating more traffic. This is an advantage over native apps which can't be discovered over search engines. They can, however, be more visible on the app store via App Store Optimization(ASO).

Drawbacks

The major drawbacks include:

Performance: Although PWAs can offer great performance, they may not match the overall performance of fully native apps. This is particularly true for highly intricate or resource-intensive applications. In essence, PWAs can offer a great user experience, but for very complex or demanding tasks, native apps may still have an edge.

Limited Presence in App Stores: PWAs are not easily distributed to traditional app stores like the Apple App Store or Google Play Store, which means they might have a harder time reaching users who primarily discover apps through these platforms. However, tools like PWABuilder allow developers to create packages that can be submitted to various app stores.

Functionalities: PWAs offer fewer functionalities relative to a native app. PWAs rely on web technologies and don't have full access to native device APIs. While they can access some device features through browser APIs (like geolocation or camera), they may not have the same level of access as native apps, which may utilize features such as Bluetooth, advanced camera controls, ambient light, fingerprint scanner, etc.

Let's create one!

React lets us easily create a PWA. Run the following command:

npx create-react-app my-app --template cra-template-pwa

With Typescript;

npx create-react-app my-app --template cra-template-pwa-typescript

That's all you need! The PWA template provided by React contains all the major things we need to create a PWA, including a service-worker.js file in the src/ directory.

To use the service worker, it has to be registered. We need to change serviceWorker.unregister() to serviceWorker.register() in our src/index.js file.

// from
serviceWorkerRegistration.unregister();
// to 
serviceWorkerRegistration.register();

Voila! You have enabled service workers for offline functionality and a faster load time. The service-worker.js file allows you to utilize Workbox's InjectManifest plugin, which will compile your service worker and inject into it a list of URLs to precache. The service worker will use a cache-first strategy for handling all requests for webpack-generated assets, including navigation requests for your HTML.

To view your changes without having to deploy to production first, you can install the serve package, create a production-ready build folder and deploy your build locally via serve.

npm install serve
npm run build
npx serve -s build

This way, when you access the 'Application' tab in Chrome Dev Tools, you will be able to see all the stages in your service worker lifecycle, check if it is active or not, assess your manifest.json file and more.

How does workbox precaching work?

This is a step-by-step process of how the workbox tool handles caching in the install and activate events of a service worker:

  • A user loads the app for the first time

  • workbox-precaching, a workbox module, removes all duplicates from the assets to be downloaded and connects the assets with relevant service worker events so they can store the assets.

  • If a URL already has versioning information, it's used as a cache key without changes. If a URL lacks versioning information, workbox adds a query parameter containing a content hash generated during the build process to serve as the cache key. It is advisable to note here that if you are generating and inserting a hash into each filename, provide a RegExp that will detect it, thereby reducing the bandwidth consumed when precaching.

  • A user revisits the app and there's a new service worker with different precached assets.

  • workbox-precaching determines what assets are completely new and which of the already present assets need updating, based on their revisioning. Then, it adds any new assets, or update revisions, to the cache during the new service worker's install event.

  • In the activate event of the new service worker, workbox-precaching will check for and remove any cached assets that are no longer present in the list of current URLs.

And that's how you have an updated cache with the latest assets whereby only updated files are downloaded, thereby boosting performance.

You can find more information on workbox-precaching here.

Conclusion

I hope you enjoyed reading this article and are considering making your website a PWA. It offers a lot of benefits that would amp up user experience and greatly reduce development costs.

For more information about how PWAs work, check out this resource.

Happy Coding!🎉