My dad bought his first vehicle, a scooter, in 2002. On the day of its delivery, as the agent handed over the keys to my dad, he said to us, “Be safe. Ride like your scooter doesn’t have brakes or horn.”
My advice to someone implementing a service worker is somewhat similar — “Deploy it as if it is the last deployment you’ll do.”
I speak from the experience I gained over the past few months building Cinepotato, a serverless PWA written in Angular with Firebase’s infrastructure on the back-end (Firestore and Hosting). Irrespective of your application’s architecture, you’ll relate to these scenarios.
1. Your users can get locked in a version
Once installed, (most default implementations of) service workers always load the cached version of your PWA. The latest deployment is detected, downloaded and cached while the user spends time on the cached version. In other words, if the user does not spend enough time on the cached version of your PWA, the latest deployment will never be successfully downloaded and cached.
Your users can land in this situation more easily than you think:
a. If the size of your PWA is too big for a network, it will take a while before the latest deployment is cached. Users may not spend enough time on the cached version since all your PWA’s functionality is already available. Example: A user doing a quick calculation on a calculator PWA and leaving it.
b. If your PWA breaks for whatever reason. Examples: A bad environment configuration (low timeout/wrong baseUrl), conflicting CSP header, etc.
Desktop browsers continue to download and cache the latest deployment even after the PWA tab is closed, provided the URL was opened and the update was detected.
2. Your PWA can make your storage inconsistent
Services like Firestore allow web apps to interface a storage directly, without needing an application layer. This means the database schema resides on the web app. Every schema change you deploy becomes available only that version onwards.
Suppose, your users read from and write to a collection called movies
in Firestore with the schema:
{
runtime: number;
title: string;
}
You cannot change runtime
to runtimeInMinutes
and expect good things to happen. Users with the cached version of the PWA will encounter failed reads and write to the database in the old schema.
This holds true for localStorage
, sessionStorage
and any other browser storage APIs too.
3. iOS support for PWAs kinda sucks
Plenty has already been written about PWAs on iOS. While Apple slowly works to push its bug-ridden elephant of a platform forward, there are some issues PWA users on iOS will face readily:
a. Unlike Android, there is no prompt to add PWAs to the user’s home screen; you will have to educate them to do that
b. It is possible to add a PWA to home screen multiple times
c. If you Add to Home Screen too quickly, the icon will simply load a tab in Safari
d. The notch adds additional height to your PWA which cannot be fixed by the viewport-fit=cover
and setting height to 100vh
produces an undesired vertical scroll (PWA height + notch height), thereby breaking any full-screen styles you might have given
Maximiliano Firtman covers PWAs on iOS in great detail and I encourage you to follow him.
For years, mobile developers have been facing the challenges of having multiple versions of their app live at once. As web apps evolve to behave more like mobile apps, it is imminent for web developers to face these challenges too.