Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Offline Web Apps (Service Workers)

Offline Web Apps (Service Workers)

2307a37297162f815342545a2068b2f1?s=128

Erik Hellman

August 03, 2017
Tweet

More Decks by Erik Hellman

Other Decks in Programming

Transcript

  1. Offline Web Apps

  2. None
  3. None
  4. Lie-fi

  5. of users abandon sites that take longer than 3 seconds

    to load 53%
  6. 60% of world-wide mobile connections are 2G

  7. Service Workers

  8. Service Workers are a client-side proxy Service worker (written in

    Javascript) Cache Web server
  9. Service Worker Lifecycle • Adds app-like lifecycle to a page

    • Wakes up only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register
  10. • Adds app-like lifecycle to a page • Wakes up

    only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register Service Worker Lifecycle
  11. Service Worker Lifecycle • Adds app-like lifecycle to a page

    • Wakes up only when the OS says • Only responds to system events Activated Error Idle Active Terminated Install Register
  12. Service Worker is for the SECOND load.

  13. Implementing a Simple Service Worker

  14. Register the Service Worker Activated Error Idle Active Terminated Install

    Register
  15. Register the Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js')

    .then(function(reg) { console.log('Service Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  16. Register the Service Worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js')

    .then(function(reg) { console.log('Service Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  17. Add an install Event Handler Activated Error Idle Active Terminated

    Install Register
  18. Add an install Event Handler self.addEventListener('install', function(event) { return self.skipWaiting();

    });
  19. Pre-fetch the App Resources Activated Error Idle Active Terminated Install

    Register
  20. Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache

    = ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
  21. Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache

    = ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
  22. Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache

    = ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
  23. Pre-fetch the App Resources var cacheName = 'app-shell-cache-v1'; var filesToCache

    = ['/', '/index.html', ...]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll(filesToCache); }).then(function() { return self.skipWaiting(); }) ); });
  24. Add an activate Event Handler Activated Error Idle Active Terminated

    Install Register
  25. Add an activate Event Handler self.addEventListener('activate', function(e) { e.waitUntil( caches.keys().then(function(keyList)

    { return Promise.all(keyList.map(function(key) { if (key !== cacheName) { return caches.delete(key); } })); }) ); return self.clients.claim(); });
  26. Add an activate Event Handler self.addEventListener('activate', function(e) { e.waitUntil( caches.keys().then(function(keyList)

    { return Promise.all(keyList.map(function(key) { if (key !== cacheName) { return caches.delete(key); } })); }) ); return self.clients.claim(); });
  27. Not Done Yet… Activated Error Idle Active Terminated Install Register

  28. None
  29. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)

    { return response || fetch(e.request); }) ); });
  30. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)

    { return response || fetch(e.request); }) ); });
  31. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)

    { return response || fetch(e.request); }) ); });
  32. Add a fetch Event Handler self.addEventListener('fetch', function(e) { e.respondWith( caches.match(e.request).then(function(response)

    { return response || fetch(e.request); }) ); });
  33. Ready to Go! Activated Error Idle Active Terminated Install Register

  34. Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service

    Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  35. Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service

    Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  36. Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/scripts/s-worker.js') .then(function(reg) { console.log('Service

    Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  37. Scope if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/service-worker.js') .then(function(reg) { console.log('Service

    Worker Registered', reg); }) .catch(function(err) { console.log('Error registering Service Worker', err); }); }
  38. Caching Strategies YOU are in control of the network

  39. Cache, Falling Back to Network Page Service Worker Network Cache

    X
  40. Network, Falling Back to Cache Page Service Worker Network Cache

    X
  41. Cache, then Network Page Service Worker Network Cache

  42. Generic Fallback Page Service Worker Network Cache X X

  43. control You are in

  44. Tools

  45. Chrome Dev Tools

  46. Chrome Dev Tools: the cache

  47. Chrome Dev Tools: the cache

  48. sw-toolbox

  49. Cache first in sw-toolbox importScripts('/sw-toolbox.js'); toolbox.router.get('/(.*)', toolbox.cacheFirst, { origin: /\.googleapis\.com$/

    });
  50. sw-precache Node module

  51. sw-precache precache.write('service-worker.js', { staticFileGlobs: ['**/*.{html,css}'], runtimeCaching: [ {urlPattern: '/', handler:

    'fastest'}, {urlPattern: '/api/.*', handler: 'networkFirst', options: {networkTimeoutSeconds: 5} }, {urlPattern: '/posts/.*', handler: 'cacheFirst'}, {urlPattern: '/styles/.*', handler: 'cacheOnly'}, {urlPattern: '/inbox.json', handler: 'networkOnly'} ] });
  52. PWA Codelab https://codelabs.developers.google.com/codelabs/your-first-pwapp

  53. Service Workers the core underpinning Progressive Web Apps

  54. Service Workers Web Apps will need to worry about lifecycle...

  55. Thank You!