A Progressive Web App is a website; all its assets are the same as on the web, but with new tools to make those assets load fast when online and available when offline.
Developing an application typically involves several assets and resources, from the logic and code (compiled or not) to the user interface elements such as screen designs, images, logos, and fonts.
A Progressive Web App is a website, so all its assets are the same as on the web:
By default, websites download assets over the network, starting with HTML and continuing to the rest of the resources.
Managing those resources to load fast and be available offline has been a challenge for the web. Nowadays, PWAs use capabilities previously associated only with platform-specific apps.
When you install a platform-specific app you are typically downloading a package that includes all the app's assets: code, images, fonts, videos, and so on. Therefore, all these resources are available, from your device storage, even when the app is offline.
On the other hand, a classic website needs a network connection to download the assets when required. If you are offline, you will see an error from the browser as there are no assets client-side.
The PWA approach enhances the traditional web experience by making some or all the assets available client-side as with platform-specific apps. Therefore, when you open a PWA, the initial rendering can be as instantaneous as a platform app because the assets are available without going to the network.
An app that is available offline will always render a basic user interface instead of a technical error from the operating system or browser. Some apps still offer all their functionality, some a limited experience, and others a simple message with the app's branding. This applies to both platform-specific apps and PWAs.
Since the beginning of the web, developers have not had complete control of how a resource is cached. The browser is in charge of the HTTP cache and it may or may not cache and serve resources based on different policies. Other storage options like Web Storage and IndexedDB were meant to save simple data and objects.
PWAs don't need to rely on those policies alone for their content. Instead, we have solutions today to gain better control over when and how to cache resources and when and how to deliver them locally: the Cache Storage API. The web has a few of client-side storage solutions available:
localStorage
and sessionStorage
. These APIs store simple key/value string pairs. Web storage is limited, and has a synchronous API, so it should be avoided whenever possible.Warning
You may have heard about WebSQL and ApplicationCache. These two solutions are deprecated, and you shouldn't use them in your PWA.
A PWA can store its assets in Cache Storage and IndexedDB, but how can we use those assets to deliver a fast and offline experience to your users. The answer? Service workers.
With a service worker, you can serve assets without going to the network, send notifications to a user, add a badge to your PWA icon, update content in the background, and even make your whole PWA work offline. Learn more about service workers in the next chapter.
Users expect your application to offer a fast and always-ready experience. That means your app should work offline.
Being offline-ready doesn't mean that all your content or services should be available without a network connection. Having at least a basic experience when the user is offline, like a page that asks you to connect to the Internet to continue, is one of the requirements of being a Progressive Web App. In some browsers this is a must-have feature to pass the PWA installation criteria. Displaying your PWA's user interface, along with cached content, is better. Letting users continue using your whole PWA and syncing server changes when they're back online is the gold standard for working offline.
To make your app available offline, you will need to cache the assets necessary for your offline experience and make your service worker serve them later. Make sure to add the offline assets to your cache before you need them. This is a particular case where you cannot cache them when requested.
Asset caching happens independently from PWA installation, and will work even from a browser tab, allowing for faster asset delivery and an offline experience regardless of how a user chooses to use your PWA.
In your PWA, you are in charge of all the decisions. You can choose the best approach to cache or install assets based on your needs. Some decisions to make are:
Gotchas
With platform-specific apps, the most common pattern is to include all the app's assets in its package; that's why these apps are commonly larger than 500 MB. On the other hand, A PWA can initially install only the minimum set of resources to offer an offline and fast experience and download the rest later, with PWAs using considerably less storage on installation.
In the standard app model for app catalog installed apps, when developers need to update their app, they publish a new package. Users need to download the whole package again, even if most of the assets haven't changed. With PWAs, using the approaches on the section above, you decide how and when to update assets. Here are different options for how to update assets:
When caching assets, you need to decide on a cache swap or clean up policy that defines when the user will see an updated asset; taking into account storage usage and the balance between a fast experience and displaying a slightly stale asset.
Usually platform-specific apps don't deal with size limits; at installation, apps can be gigabytes or more in size. As long as the device has the capacity the installation will be allowed. Also, while the app is installed, it will use that total amount of storage no matter if you use the app or not. Storage is handled differently for PWAs. The browser will store your assets based on policies that you define in your PWA's logic.
The users are always in control, and they can delete the assets at any time. For PWAs, manual eviction happens via the browser's settings.
Size limits depend on the browser. It's not as flexible as for platform-specific apps, but it's typically good enough for most web apps. You can find the specific limitations by browser in this article.
Browsers can evict assets based on storage pressure, or after some weeks of inactivity, if the user is using your PWA in the browser. On some platforms, if the user installs your PWA, eviction won't happen. Where available, code can request persistent storage through an API to avoid that eviction.
If storage eviction happens for any reason and the user installed your PWA, the PWA will still work if you have a network connection. When you open that app again, the browser will start the service worker lifecycle again, loading your app from the network.