Shower Presentation Engine

Yours Truly, Famous Inc.

What you need to know to start development of PWA

Vitalii Rybka
Dnipro JS
Feb 20, 2020

Slides

Agenda

Why PWA

Mobile vs. Desktop

Why PWA

Distributing Native Software is HARD

Why PWA

Every Step Costs You 20% of Users

© ComScore

Why PWA

Existing solutions:

Benefits

Main PWA Components

Web App Manifest

      {
        "name": "Dark Sky Weather PWA",
        "short_name": "Weather",
        "icons": [{...}],
        "start_url": "/index.html",
        "display": "standalone",
        "background_color": "#3E4EB8",
        "theme_color": "#2F3BA2"
      }
    

Web App Manifest

      {
        "name": "Dark Sky Weather PWA",
        "short_name": "Weather",
        "icons": [{...}],
        "start_url": "/index.html",
        "display": "standalone",
        "background_color": "#3E4EB8",
        "theme_color": "#2F3BA2"
      }
    

Web App Manifest

      {
        "name": "Dark Sky Weather PWA",
        "short_name": "Weather",
        "icons": [{...}],
        "start_url": "/index.html",
        "display": "standalone",
        "background_color": "#3E4EB8",
        "theme_color": "#2F3BA2"
      }
    

Web App Manifest

      {
        "name": "Dark Sky Weather PWA",
        "short_name": "Weather",
        "icons": [{...}],
        "start_url": "/index.html",
        "display": "standalone",
        "background_color": "#3E4EB8",
        "theme_color": "#2F3BA2"
      }
    

ServiceWorker

Where should I put service-worker.js?

ServiceWorker Lifecycle

ServiceWorker Install Lifecycle

      ...
      self.addEventListener('install', (evt) => {
        evt.waitUntil(
          caches.open(CACHE_NAME).then((cache) => {
            return cache.addAll(FILES_TO_CACHE);
          })
        );
        self.skipWaiting();
      });
    

ServiceWorker Activate Lifecycle

      ...
      self.addEventListener('activate', (evt) => {
        ...
            return Promise.all(keyList.map((key) => {
              if (key !== CACHE_NAME && key !== DATA_CACHE_NAME) {
                return caches.delete(key);
              }
      ...
      self.clients.claim();
    

ServiceWorker Fetch Lifecycle

      ...
      self.addEventListener('fetch', (evt) => {
        ...
        if (evt.request.url.includes('/forecast/')) {
          return fetch(evt.request)
            .then((response) => {
              ...
          }
        }

      ...
    

ServiceWorker Fetch Lifecycle

      ...
      self.addEventListener('fetch', (evt) => {
        ...
        evt.respondWith(
          caches.open(CACHE_NAME).then((cache) => {
            return cache.match(evt.request).then((response) => {
              return response || fetch(evt.request);
          });
        })

      );
    

Advanced tools for PWA

Lighthouse CI

GoogleChrome/lighthouse-ci

Lighthouse CI with GitHub Actions

      name: Build project and Run Lighthouse CI
      on: [push]
      jobs:
        lhci:
          name: Lighthouse CI
          runs-on: ubuntu-latest
            steps:
      ...
    

GoogleChrome/lighthouse-ci Getting Started

Lighthouse CI with GitHub Actions

Lighthouse CI with GitHub Actions Real Example

Real Example

Frameworks and libs for PWA

Case studies

Case studies. Trivago

More Info

Case studies. BMW

More Info

Case studies. Pinterest

More Info

Useful links

Weather PWA

About me

Fork me on GitHub