Build a minimal
Progressive Web App

MAKE IT INSTALLABLE

W3C Manifest

https://w3c.github.io/manifest/

Basic Manifest.Json

{
  "name": "Minimal PWA",
  "short_name": "PWA",
  "description": "My Tiny PWA",
  "start_url" : "/",
  "orientation": "any",
  "scope": "/",
  "display": "standalone",
  "theme_color": "#003781",
  "background_color": "#003781",
  "icons": [{
    "src": "icon_192.png",
    "sizes": "192x192"
  },{
    "src": "icon_512.png",
    "sizes": "512x512"
  }]
}

Place this content to your application root in a file named : manifest.json

Do not forget the icons : http://cthedot.de/icongen/

Register-it to your index.html

<!doctype html>
<html lang="fr">
    <head>
        <link rel="manifest" href="manifest.json">
        <meta name="theme-color" content="#317EFB"/>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        <h1> My Tiny PWA </h1>
    </body>
</html>
$http-server -p 8080

Test it on an http server, ex : 

Install http-server via yarn or npm

$npm install -g http-server
$yarn global add http-server

or use this chrome plugin

Open chrome dev tools

Check your manifest.json configurations

ENABLE
OFFLINE USE

Service Worker !

1 - Register


  <script>
    if ('serviceWorker' in navigator) {
      console.log("Will the service worker register?");
      navigator.serviceWorker.register('service-worker.js')
        .then(function(reg){
          console.log("Yes, it did.");
        }).catch(function(err) {
          console.log("No it didn't. This happened: ", err)
        });
    }
  </script>
  • Create a file named "service-worker.js"
  • Register service worker using navigator API :
    Add the following to your "index.html"

Now navigator can find out service worker on your page, check it !

2 - Install

self.addEventListener('install', function(e) {
 e.waitUntil(
   caches.open('tinyPWA').then(function(cache) {
     return cache.addAll([
       '/',
       '/index.html'
     ]);
   })
 );
});

At the load "install" event is triggered

We can use the event to cache some files,
add the following to your "service-worker.js" file :

Now service worker add to cache index.html, check it !

3 - Fetch

self.addEventListener('fetch', function(event) {
  console.log(event.request.url);
  event.respondWith(
    caches.match(event.request).then(function(responseFromCache) {
      if(responseFromCache === undefined) {
        return fetch(event.request)
      } else {
        return responseFromCache
      }
    })
  );
});

At every request "fetch" event is triggered

We can use this event to distribute cached files instead of asking the web server :

Now when requested "index.html" we get the cached "index.html",

check it !

We are Offline !!!

Now update your index.html

We can't update our files...

Application update

</>

Managing
App
Cache

 

What do we want ?

  • cache only : performance
     
  • network only : default behaviour
     
  • cache falling back to network : backup
     
  • network falling back to cache : fresh data
     
  • cache then network : performance with fresh data

Fresh Data

If network success then cache & return response
else  return cache response

self.addEventListener('fetch', function(event) {
  console.log(event.request.url);
  event.respondWith(
    fetch(event.request).then(function(response) {
      caches.open("tinyPWA").then(function(cache) {
        cache.match(event.request).then(function (){
              cache.put(event.request, response.clone());
              console.log("cache updated");
        });
      });
      console.log("Response from network");
      return response.clone();
    }).catch(function (){
      return caches.match(event.request).then(function(response) {
        if(response){
          console.log("Response from cache");
          return response;
        } else {
          fetch(event.request.clone());
        }
      });
    })
  )
});

Delete unused cache

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName){
          return "tinyPWAV1" !== cacheName
        }).map(function(cacheName) {
            return caches.delete(cacheName);
        })
      );
    })
  );
});

Understand service worker update

Ouf !
Eh man ! Can we do something better ?

Yes !!!
Forget everything ;) Use Angular !

#4 courses-PWA-minimal-build 2021

By orangefire

#4 courses-PWA-minimal-build 2021

  • 317