DEV Community

Ziad Amr
Ziad Amr

Posted on • Originally published at ziadamrme.vercel.app

Progressive Web Apps: From Browser to Home Screen

Progressive Web Apps (PWA) changed my perspective on how a web app can reach users. Before working with PWA, I saw web apps as limited compared to native mobile apps — no offline access, no notifications, no home screen icon. But with PWA, I was able to significantly close that gap. In this article, I'll share my practical experience with PWA in Esma3 Radio and Weather App.

The first thing I did was in Esma3 Radio. This app is primarily used on mobile — people listen to radio while commuting, at the gym, or walking. So it made sense to make it work as an installable app. I started with a manifest.json file that provides the browser with all the information it needs: app name, icons in various sizes, theme color, and screen orientation. When a user visits the site for the first time, the browser suggests installing the app on their home screen. The install rate was around 30% of users — a pretty solid number.

The Service Worker was the fundamental element. This is a script that runs in the background and controls all network requests. In Esma3 Radio, I used a Cache First strategy for CSS, JavaScript, and font files — meaning they're fetched from the internet the first time, then stored in the cache and served from there every subsequent time. This made the app load almost instantly after the first visit. For station data, I used Network First — it tries to fetch from the internet first, and if that fails, it falls back to the cache.

Offline support in Esma3 Radio was a unique challenge. When the user is offline, they obviously can't listen to live radio, but I was able to display a clear "You're not connected to the internet" message along with previously loaded stations as reference. I also made sure the app icon and splash screen appear even without internet — this makes the user feel it's a real app, not just a website.

In the Weather App, the challenge was different. Weather data changes roughly every hour, so the caching strategy needs to be smart. I used Stale-While-Revalidate — I display the old data from the cache immediately, while simultaneously requesting fresh data from the internet. When the new data arrives, I update the screen. This gives a sense of speed because the user sees something instantly, while the data is as fresh as possible.

The biggest problem I faced was updating the Service Worker itself. When I deploy a new version of the app, the old Service Worker continues running until the user closes all tabs and reopens the app. This means a user might see the old version for days! The solution was to use skipWaiting and clientsClaim so the new Service Worker takes effect immediately. But this introduces another problem — if there's an ongoing request, it might conflict with the new cache. That's why I show an "Update available — click here to update" message instead of forcing the update on users.

The install prompt experience was a key point. The browser suggests installation automatically, but this sometimes happens at a non-ideal time. I used the beforeinstallprompt event to intervene and show a custom install message at the right moment — for example, after a user has been listening to radio for 5 minutes, I show "Install Esma3 Radio on your phone for quick access." This custom message increased the install rate by 40% compared to the browser's default prompt.

The differences between PWA and native apps still exist — no full access to all system APIs, and performance isn't exactly like a native app. But for Arabic users whose usage is predominantly mobile, PWA provides an excellent experience without needing to download an app from the store. In Esma3 Radio, 60% of usage is from mobile, and PWA made the experience much closer to a native app.

My advice for anyone wanting to add PWA to their app: start with the basics — manifest.json and a simple Service Worker that caches static files. Then gradually add advanced caching strategies. Don't try to do everything at once. And test on real devices — the emulator doesn't represent the real user experience. Also, pay attention to the install experience — a custom prompt makes a real difference.


Powered by Ziad Amr

Top comments (0)