loading...

Let's start with PWA

ekansss profile image ekanSSS ・4 min read

One off the most prometting technology that show up these last year are Progressive Web Apps(PWA). No more pain for building an app per mobile store, each with their constraint and specificity (store rules, language, platform limitation, ect), your website IS your application, and it work (at this time) in a lots of Androids and latest iOs (https://caniuse.com/#feat=serviceworkers)

But even is this tech is awesome, it is easy to get lost when you want to build your own PWA, due to his youth, there are not so much tuturials or even solutions on stackOverflow.

What will you learn

  • Build a PWA
  • Use ServiceWorker
  • Use Offline fonctionality

What you will not learn

  • Use of framework like Workbox.js
  • Ultimate answer of life, universe and everything else (sorry !)

Let's start

Requirements

To make a mobile client install a pwa, (with a native popup on android for exemple), you neede to achieve some requierements :

  • Your site must be on HTTPS
  • Have a valid webmanifest
  • Register a service worker

HTTPS

I'm not going to explain how to set your site on https, sevrals tuto already exist on this subject, but if your goal is just to discover and test PWA, this part is not required is you local server use http://localhost/ on chrome as multiple security check are turn off on this url like https requirement for service worker !

Webmanifest

One easy thing to do, is to implement a correct webmanifest to tell navigator you have an PWA ! so let's do it

<!-- in your html head -->
<link rel="manifest" href="/manifest.json">
// in /manifest.json
{
  "short_name": "PWA",
  "name": "My first PWA",
  "icons": [
    {
      "src": "/images/icons-192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/images/icons-512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/?source=pwa",
  "background_color": "#000000",
  "display": "standalone",
  "scope": "/",
  "theme_color": "#FFFFFF"
}

There aren't so mch things to say here, except that name(or short_name), icons, start_url and display are required.

You can find more information on webmanifest for PWA here : https://developers.google.com/web/fundamentals/web-app-manifest/

Service Worker

This is it, heart of any PWA, a Service Worker(SW) but you can be wondering what is it and what it do ?

  • It's a Javascript worker so it can receive instruction, even when your PWA or navigator is closed.
  • Act as a fully configurable network proxy, to handle offline case.

One thing to know about SW is it's heavily rely on promise, so if you don't understand it, I advise you to learn a little about it !

Register a SW
<script type="text/javascript">
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js', {'scope': '/').then(function(registration) {
    // Registration was successful
    console.log('ServiceWorker registration successful with scope: ', registration.scope);
  }, function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
  });
}
</script>

Just put it a before </body> for exemple

This is a basic SW registration, we test if navigator support fonctionnality then we just add it to client. Pretty simple no ?

Scope of service worker is important ! If it's at site root, it can listen to any request from anyhere in your site, but if it's in /assets/ it will only listen to request comming from /assets/* pages.

Lifecycle

SW have an "Apps" like life cycle, let's see it.

service worker lifecycle

One off most important thing to reminder is that Service Worker is active beyond your website tabs, it's directly executed in browser so it's still alive and ready when an user close your site, permitting him to received push notification or content sync at anytime !

Let's begin

Now that everything is ready, let's code your first service worker with basic installation

//sw.js
const cacheName = 'my-cache';
const filesList = [
  '/assets/style.css',
  '/assets/main.js'
];
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(cacheName)
      // Add your file to cache
      .then( (cache) => {
        return cache.addAll(filesList);
      })
      // Tell SW to end 'waiting' state
      .then(() => self.skipWaiting())
  );
})

self.addEventListener('activate', (event) => {
  event.waitUntil(
    // tell browser to use this service worker and not outdated one
    self.clients.claim()
  );
})

To see if your SW have corectly installed, on chrome for exemple, open DevTools and go in Application tab, you should see something like this :

DevTools Service Worker

PWA

Now that your first SW is ready, let's upgrade it to a pwa, and to achieve this goal, we only need to make your Service Worker respond with something, like a generic offline page, when we aren't online.

const cacheName = 'my-cache';
const offlinePage = '/offline.html';
const filesList = [
  '/assets/style.css',
  '/assets/main.js',
  offlinePage
];
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(cacheName)
      // Add your file to cache
      .then( (cache) => {
        return cache.addAll(filesList);
      })
      // Tell SW to end 'waiting' state
      .then(() => self.skipWaiting())
  );
})

self.addEventListener('activate', (event) => {
  event.waitUntil(
    // Tell browser to use this service worker and not outdated one
    self.clients.claim()
  );
})

self.addEventListener('fetch', (event) => {
  // If we don't have internet connection and it's a navigation request
  if (!navigator.onLine && event.request.mode === 'navigate') {
    event.respondWith( caches.open(cacheName)
      .then( (cache) => {
        // If we find our offline page in cache, respond with it
        return cache.match(offlinePage)
          .then( (response) => response);
      })
    );
  } else {
    // Return null let browser do his normal behavior
    return;
  }

So we just add on more file to get cached at beginning and a fetch listener. For those who wonder, this transform your SW into a local proxy, so every request comming from your website will be catch by your Service Worker and processed before doing anything (like let request pass or directly respond with a cached file).

Enjoy

Your first PWA is now ready to use ! for those who just want a fast try, I make a fully fonctionnal github.

GitHub logo ekanSSS / pwa

some test and work on pwa

PWA tutorial

Here you can easily test PWA basic,

install

Get repo in local and go on index.html. wait for service worker to install then cut your internet connection and try to reload page

PS: don't forgetted to be on https or on http://localhost on chrome

Posted on by:

ekansss profile

ekanSSS

@ekansss

Front End developper who love testing weird coding stuff, especially when it touch PWA

Discussion

pic
Editor guide