My first Progressive Web App

desktop version

It is been almost 1.5 years since heard term Progressive Web Apps (PWA) for very first time while watching Chrome Dev Summit live stream, and since then implemented small components from PWA in my daily work.

A month ago decided to create small PWA just to prove and combine what I learned during past year, so I started small side project.

TL;DR
The complete code could be find here, and demo of the project at https://willrain.today

Beginning

The idea was to build my own weather app, and because my target was to build as minimal as possible app as a size, I decided to use preact.js ( really good alternative to react in just 3kb ). Using latest JS features natively ( ES2015/16, fetch, async,await) and not transpiling and including any polifills ( my app does not work on ios, sorry) helped me to achieve the goal: JS is 13kb and 4kb of CSS, which is not bad.

Reliable

That means your app is always available even on flacky connection or no internet at all, to achieve that I had to use magical ServiceWorker, which is kind of network proxy that can intercept all network requests. Chrome team created a library for that - sw-toolbox, all I need to do is precache my files, so they are always available even in offline mode.

toolbox.precache(['/', 'main.js', 'main.css']);
toolbox.router.default = global.toolbox.networkFirst;

The app makes API request to receive latest forecast, but sometimes that could take time, so storing data in IndexDB sounds like good idea, for that I am using idb-keyval super minimal keyval store implemented with IndexedDB. When a user opens the app, immediately can see stored data, while network request is coming.

Fast

As already said, app is small, only 40kb initial payload, including service worker and all libraries, and SW will cache everything, so second open of the app is instantly.
Preact.js similar to react uses virtual DOM, so app is quite fast while rendering. Using only transform and opacity for animations also helps.


small transition between icons

Engaging

That part includes application icon, so user can lunch app from desktop, and push notifications showing what is forecast for a day, every morning for example.

Creating lunch icon is probably the easiest thing, it is just a json file ( manifest.json ), in which have to specify, url to icon, app name, theme color and app orientation.

{
"short_name": "WillRain",
"name": "Will Rain Today",
"icons": [
{
"src": "./assets/icons/launcher-icon-2x.png",
"sizes": "96x96",
"type": "image/png"
},
],
"scope": "/",
"display": "standalone",
"orientation": "portrait",
"background_color": "#3374ff",
"theme_color": "#3374ff"
}

Push notifications need more work and lots of configuration ( even some backend work ), first have to take google cloud messaging key and store in manifest, second add listener to push event in your service worker, in my case looks like that, and finally ask user to give you permission to send push notifications

self.addEventListener('push', function(event) {
const title = 'Mostly cloudy -9';
const options = {
body: '3% rain | feels like -15',
icon: 'images/icon.png',
};
event.waitUntil(self.registration.showNotification(title, options));
});
push notification on locked screen & lunch icon from home screen

Making a modern PWA is not easy, but is something that definitely worth it for your users. The complete code could be find here, and demo of the project at https://willrain.today