Save 37% off PRO during our Black Friday Sale! »

Service Workers - Beyond The Cache (NDC Sydney)

8ec1383b240b5ba15ffb9743fceb3c0e?s=47 Phil Nash
September 19, 2018

Service Workers - Beyond The Cache (NDC Sydney)

Service workers are here to stay, they're live in (almost!) all the major browsers and all your favourite frameworks offer them out of the box for caching your application offline. This is a great start for building modern, resilient, progressive web applications. But only using the service worker's cache is like driving a sports car in 3rd gear at the most.

We'll dive into push notifications, background sync and other experimental service worker features, showing what they can be used for and how to integrate them in your app. Together we'll see how to make your web apps appier and your users happier.

--

Links:

The demo app: https://github.com/philnash/sms-messages-app

Push notification docs: https://developers.google.com/web/fundamentals/codelabs/push-notifications/
Web push libs: https://github.com/web-push-libs
UX of push notification permissions: https://developers.google.com/web/fundamentals/push-notifications/permission-ux
Permissions on the web suck: https://philna.sh/blog/2018/01/08/permissions-on-the-web-suck/

Background sync example: https://www.twilio.com/blog/2017/02/send-messages-when-youre-back-online-with-service-workers-and-background-sync.html

Experimenting with background fetch: https://philna.sh/blog/2017/07/04/experimenting-with-the-background-fetch-api/

8ec1383b240b5ba15ffb9743fceb3c0e?s=128

Phil Nash

September 19, 2018
Tweet

Transcript

  1. SERVICE WORKERS BEYOND THE CACHE

  2. Phil Nash @philnash http:/ /philna.sh philnash@twilio.com

  3. SERVICE WORKER

  4. Service Worker Support ✅ ✅ ✅ ✅ ✅ @philnash

  5. None
  6. CACHING @philnash

  7. @philnash

  8. BETTER RESILIENCY BETTER PERFORMANCE @philnash

  9. BETTER EXPERIENCES @philnash

  10. BEYOND THE CACHE @philnash

  11. PUSH NOTIFICATIONS BACKGROUND SYNC @philnash

  12. PUSH NOTIFICATIONS

  13. Push Noti cation Support ✅ ✅ ✅ ❌ ✅ @philnash

  14. @philnash

  15. 74.86% GLOBALLY — caniuse.com @philnash

  16. PUSH NOTIFICATIONS ARE INCREDIBLY USEFUL @philnash

  17. Good noti cations • Appointment reminders • Chat alerts •

    ETA alerts • Event updates @philnash
  18. TIMELY, ACTIONABLE AND PERSONAL @philnash

  19. TIMELY @philnash

  20. Timely noti cations "Daisy just sent you a message" "Your

    car is here now" "You can check in now" @philnash
  21. @philnash

  22. @philnash

  23. IN TIME AT THE RIGHT TIME OF DAY, IN THE

    RIGHT TIME ZONE, THE RIGHT NUMBER OF NOTIFICATIONS @philnash
  24. ACTIONABLE @philnash

  25. Actionable noti cations "Daisy sent you a message" "Your car

    is here now" "You can check in now" @philnash
  26. PERSONAL @philnash

  27. Personal noti cations "Daisy sent you a message" "Your car

    is here" "You can check in now" @philnash
  28. HOW TO PUSH @philnash

  29. @philnash

  30. VAPID @philnash

  31. VOLUNTARY APPLICATION SERVER IDENTIFICATION FOR WEB PUSH @philnash

  32. VOLUNTARY APPLICATION SERVER IDENTIFICATION FOR WEB PUSH @philnash

  33. VAPID (Node.js) npx web-push generate-vapid-keys ======================================= Public Key: BPARzOEvMc0MkHDN7TT25vorJ1vA9pmbEVUE6T-C6Ori3f8hylaeflA89QF... Private

    Key: 0mLkNulmnEB1jQxvrZ7hyWDfbWMQh2IcdxmeZtEbUIw ======================================= @philnash
  34. VAPID (C#) VapidDetails vapidKeys = VapidHelper.GenerateVapidKeys(); Console.WriteLine("Public {0}", vapidKeys.PublicKey); Console.WriteLine("Private

    {0}", vapidKeys.PrivateKey); 01. 02. 03. @philnash
  35. VAPID Subscribe to push noti cations with public key Sign

    a JWT with private key when sending a push This identi es your application @philnash
  36. Subscribe to noti cations const convertedVapidKey = urlBase64ToUint8Array( window.vapidPublicKey );

    01. 02. 03. @philnash
  37. Subscribe to noti cations navigator.serviceWorker.ready.then(registration => { registration.pushManager .subscribe({ userVisibleOnly:

    true, applicationServerKey: convertedVapidKey }) }); 01. 02. 03. 04. 05. 06. 07. @philnash
  38. Subscribe to noti cations registration.pushManager.subscribe({ ... }).then(subscription => { fetch('/push/subscription',

    { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(subscription.toJSON()) }); }); 01. 02. 03. 04. 05. 06. 07. @philnash
  39. Subscription { endpoint: 'https://fcm.googleapis.com/fcm/send/f3N3TXN...', expirationTime: null, keys: { p256dh: 'BKuQYOiY2gicUmqPh9MVVDoWjYbi1kby2tgBEjt-tDU...',

    auth: '-Nri1DXMcRW_WheTK4lU8w' } } 01. 02. 03. 04. 05. 06. 07. 08. @philnash
  40. Send Noti cation (Node.js) const webPush = require('web-push'); webPush.setVapidDetails( 'mailto:philnash@twilio.com',

    config.vapidPublicKey, config.vapidPrivateKey ); 01. 02. 03. 04. 05. 06. @philnash
  41. Send Noti cation (Node.js) webPush.sendNotification( subscription, JSON.stringify(data) ); 01. 02.

    03. 04. @philnash
  42. Send Noti cation (C#) using WebPush; var subscription = new

    PushSubscription(pushEndpoint, p256dh, auth); var vapidDetails = new VapidDetails(subject, publicKey, privateKey); var webPushClient = new WebPushClient(); webPushClient.SendNotification(subscription, "payload", vapidDetails); 01. 02. 03. 04. 05. 06. @philnash
  43. Receive noti cation (service worker) self.addEventListener('push', event => { const

    data = event.data.json(); event.waitUntil( self.registration.showNotification(data.title, { body: data.body, }) ); }); 01. 02. 03. 04. 05. 06. 07. 08. @philnash
  44. Libraries https:/ /github.com/web-push-libs @philnash

  45. DEMO

  46. WE NEED TO TALK ABOUT... @philnash

  47. PERMISSIONS

  48. Ketan Joshi @KetanJ0 Dear website, - I don't want you

    to post notifications to my desktop - I don't want to subscribe to your thing via a popup - I don't want you to know my location - Please stop autoplaying that video - I am angry and sad now 7:17 PM - May 13, 2018 31K 8,535 people are talking about this @philnash
  49. WEB DEVELOPERS ARE MAKING USERS SAD AND ANGRY @philnash

  50. Permissions • Push noti cations • Geolocation • Media Devices

    • Bluetooth, MIDI, WebUSB... @philnash
  51. @philnash

  52. @philnash

  53. @philnash

  54. @philnash

  55. @philnash

  56. NO CONTEXT @philnash

  57. STOP THIS!

  58. @philnash

  59. PLEASE

  60. DO NOT DEMAND NOTIFICATION PERMISSIONS ON PAGE LOAD @philnash

  61. WORRY

  62. PERMISSIONS WILL BECOME THE NEW POPUPS @philnash

  63. @philnash

  64. @philnash

  65. PLEASE

  66. DO NOT DEMAND NOTIFICATION PERMISSIONS ON PAGE LOAD @philnash

  67. SUGGESTIONS

  68. WAIT @philnash

  69. @philnash

  70. @philnash

  71. UNLESS IT'S OBVIOUS @philnash

  72. @philnash

  73. LET THEM OPT OUT WITHIN YOUR APPLICATION @philnash

  74. @philnash

  75. THE ALTERNATIVE? @philnash

  76. @philnash

  77. USE PUSH NOTIFICATIONS FOR GOOD @philnash

  78. BACKGROUND SYNC

  79. IF CACHES ARE FOR GET REQUESTS @philnash

  80. THEN BACKGROUD SYNC IS FOR POST REQUESTS @philnash

  81. Background sync • Sending messages • Posting comments • Adding

    to a shopping cart • Liking or favouriting @philnash
  82. @philnash

  83. @philnash

  84. @philnash

  85. BACK ONLINE API

  86. Background Sync Support ✅ ✅ ❌ ❌ ❌ @philnash

  87. Background Sync Support ✅ ✅ ✅ ✅ @philnash

  88. 67.87% GLOBALLY — caniuse.com @philnash

  89. INDEXEDDB @philnash

  90. The plan 1. Request fails due to network 2. Save

    request data in IndexedDB 3. User comes back online 4. Sync event res, replay request @philnash
  91. Register for Sync event fetch(url, { ... }).catch(err => {

    navigator.serviceWorker.ready.then(reg => { saveDataToIndexedDB(); reg.sync.register('fail'); }); }); 01. 02. 03. 04. 05. 06. @philnash
  92. Service worker sync event self.addEventListener('sync', event => { getDataFromIndexedDB().then(data =>

    { sendData(data); }); }); 01. 02. 03. 04. 05. @philnash
  93. DEMO

  94. LIBRARIES

  95. @philnash

  96. Workbox const bgSyncPlugin = new workbox.backgroundSync.Plugin('myQueueName', { maxRetentionTime: 24 *

    60 // Retry for max of 24 Hours }); workbox.routing.registerRoute( /\/api\/.*\/*.json/, workbox.strategies.networkOnly({ plugins: [bgSyncPlugin] }), 'POST' ); 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. @philnash
  97. ENHANCE YOUR FORMS WITH BACKGROUND SYNC @philnash

  98. EXPERIMENTAL

  99. BACKGROUND FETCH

  100. On the page navigator.serviceWorker.ready.then(function(reg) { const url = "https://example.com/largeFile.mp3"; reg.backgroundFetch.fetch('downloads',

    [url], { icons: [], title: 'Downloading largeFile.mp3', totalDownloadSize: 1048576 }); }); 01. 02. 03. 04. 05. 06. 07. 08. @philnash
  101. In the service worker self.addEventListener('backgroundfetched', function(event) { if (event.tag ===

    'downloads') { event.updateUI('largeFile.mp3 downloaded.'); // add the file to the cache } }); 01. 02. 03. 04. 05. 06. @philnash
  102. Background fetch • Audio and video • Games • WebAssembly

    @philnash
  103. CONCLUSION

  104. None
  105. Not just features • Push noti cations • Background Sync

    • Background Fetch @philnash
  106. BETTER EXPERIENCES @philnash

  107. THANKS!

  108. Icon Credits • Browser by Kimmi Studio from the Noun

    Project • Cloud by Kimmi Studio from the Noun Project • Gears by TS Graphics from the Noun Project • wi by i cons from the Noun Project @philnash
  109. None
  110. Thanks! @philnash http:/ /philna.sh philnash@twilio.com