Maxim Salnikov
@webmaxru
Maxim Salnikov
@webmaxru
npm install serve -g
git clone https://github.com/webmaxru/pwa-for-production
cd pwa-for-production
git checkout part-1
npm install
serveRecommended to copy code snippets from
Optional
Full-Stack Developer, PWAdvocate
What are the cons and challenges of the manually written service workers
Introducing Workbox
Automating application shell lifecycle: from building to serving
Organizing a proper UX for the app update
Runtime caching: strategies
Proper registration of Workbox in your app
My App
App
Service-worker
Browser/OS
Event-driven worker
Cache
fetch
push
sync
self.addEventListener('install', event => {
  
    // Use Cache API to cache html/js/css
})self.addEventListener('activate', event => {
  
    // Clean the cache from the obsolete app shell versions
})self.addEventListener('fetch', event => {
  if (event.request.url.indexOf('/api') != -1) {
    event.respondWith(
      // Network-First Strategy (for API?)
    )
  } else {
    event.respondWith(
      // Cache-First Strategy (for app shell?)
    )
  }
})# Installing the Workbox Node module
$ npm install workbox-build --save-dev// We will use injectManifest mode
const {injectManifest} = require('workbox-build')
// Sample configuration with the basic options
var workboxConfig = {...}
// Calling the method and output the result
injectManifest(workboxConfig).then(({count, size}) => {
    console.log(`Generated ${workboxConfig.swDest},
    which will precache ${count} files, ${size} bytes.`)
})// Sample configuration with the basic options
var workboxConfig = {
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{txt,png,ico,html,js,json,css}'
  ],
  swSrc: 'src/workbox-service-worker.js',
  swDest: 'dist/sw.js'
}
// Importing Workbox itself from Google CDN
importScripts('https://googleapis.com/.../workbox-sw.js');
// Precaching and setting up the routing
workbox.precaching.precacheAndRoute([])
Caching, serving, managing versions
[
  {
    "url": "index.html",
    "revision": "34c45cdf166d266929f6b532a8e3869e"
  },
  {
    "url": "favicon.ico",
    "revision": "b9aa7c338693424aae99599bec875b5f"
  },
  ...
]{
  "scripts": {
    "build-pwa": "npm run build-app &&
                  node workbox-build-inject.js"
  }
}self.addEventListener('fetch', event => {
  if (event.request.url.indexOf('/api/breakingnews') != -1) {
    event.respondWith(
      // Network-First Strategy
    )
  } else if (event.request.url.indexOf('/api/archive') != -1 {
    event.respondWith(
      // Cache-First Strategy
    )
  }
})workbox.routing.registerRoute(
  new RegExp('/api/breakingnews'),
  new workbox.strategies.NetworkFirst()
);workbox.routing.registerRoute(
  new RegExp('/api/archive'),
  new workbox.strategies.CacheFirst({
    plugins: [...]
  })
);A new version of the app is available. Click to refresh.
const updateChannel = new BroadcastChannel('app-shell');
updateChannel.addEventListener('message', event => {
    // Inform about the new version & prompt to reload
});workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('app-shell')
]);// Feature detection
if ('serviceWorker' in navigator) {
  // Postponing the registration for better performance
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js');
  });
}import { Workbox } from 'workbox-window';
if ('serviceWorker' in navigator) {
    const wb = new Workbox('service-worker.js');
    // Event listeners...
    wb.register();
}$ npm install workbox-window<script type="module">
import {Workbox} from 'https://...cdn.com/workbox-window.mjs';
if ('serviceWorker' in navigator) {
  const wb = new Workbox('service-worker.js');
  wb.register();
}
</script>wb.addEventListener('installed', event => {
  if (event.isUpdate) {
  // Show "Newer version is available. Refresh?" prompt
  } else {
  // Optionally: show "The app is offline-ready" toast
  }
});
workbox.core.skipWaiting()
workbox.core.clientsClaim()wb.addEventListener('activated', (event) => {
  // Service worker activated
});wb.addEventListener('waiting', (event) => {
  // Service worker was installed but can't be activated
});externalinstalled, externalwaiting, externalactivatedIntro to push notifications, required parties, flow
Important notice on notifications UX
The latest stable PWA API for large resources downloading: background fetch
APIs of the Project Fugu: let's code something that will be only available soon!
Course summary: testing your PWA in Lighthouse
Other famous PWA case studies for your inspiration
Maxim Salnikov
@webmaxru
Maxim Salnikov
@webmaxru