Service Worker registration & lifecycle

1ff811939fd0923df8321ec6d8bf9d4b?s=47 Jxck
May 18, 2016

Service Worker registration & lifecycle

Step forward Understanding Service Worker Registration & Lifecycle
at Frontend Meetup Tokyo vol.2 2016/5/18
Jxck

1ff811939fd0923df8321ec6d8bf9d4b?s=128

Jxck

May 18, 2016
Tweet

Transcript

  1. Service Worker registration/lifecycle Frontend Meetup Tokyo vol.2 2016/5/18 Jxck

  2. • id: Jxck • github: Jxck • twitter: @jxck_ •

    blog: https://blog.jxck.io • podcast: http://mozaic.fm • Love: music Jack
  3. mozaic.fm ep17 3 Service Worker w/ @kinu, @nhiroki_ http://mozaic.fm/post/117004083098/17-service-worker

  4. 中級者向け Service Worker Tutorial 4 https://blog.jxck.io/entries/2016-04-24/service-worker-tutorial.html

  5. Todays Talk 5

  6. Next Step of Introduction 6 • Go Deeper / Understand

    Examples Well • Good Introductions ◦ https://serviceworke.rs/ ◦ https://jakearchibald.com/2014/offline-cookbook/ ◦ http://www.html5rocks.com/ja/tutorials/service- worker/introduction/ ◦ More • Focus on … ◦ Registration ◦ Update ◦ Scope
  7. Service Worker 7

  8. Workers class Hero 8 • Service Worker (got back together)

    • Shared Worker • Web Worker • App Cache (broke up)
  9. I'm free to be whatever I 何になるのも俺の自由だ Whatever I choose

    何を選ぶのも俺の自由だ And I'll hook the request if I want その気になればリクエストだってフックしてやる 9 https://youtu.be/zUADzarhFyA
  10. Architecture 10

  11. 11 Architecture

  12. 12 Controller/Client • Controller controls Client ◦ Client = Window

    ◦ Controller = Service Worker
  13. 13 Event with Client • Controller hooks HTTP request from

    Client • Controller talks with Client via message
  14. 14 Event with Network • Controller hooks push from network

    • Controller hooks change from offline -> online
  15. 15 websocket • Controller doesn’t hooks client WebSocket • Controller

    also talks WebSocket
  16. 16 worker/db • Controller also Use WebWorker / IndexedDB •

    No LocalStorage because Sync I/O • Separate Context between Client
  17. 17 cache • Client/Controller has Cache API • Before browser

    cache • Means fetch from SW hits browser cache
  18. 18 Architecture

  19. Lifecycle 19

  20. Lifecycle 20

  21. Install SW 21

  22. register() navigator.serviceWorker.register('worker.js') .then((registration) => { return navigator.serviceWorker.ready; }); 22 self.addEventListener('install',

    (e) => { console.info('install', e); }); self.addEventListener('activate', (e) => { console.info('activate', e); }); master.js worker.js
  23. register() -> oninstall 23 • Browser fetches script • Install

    it • Fires oninstall • Prepare cache or migrate schema Ver. 1
  24. installed -> waiting 24 • Installed script moves to waiting

    • Waiting waits to be active • If no active script available, through to active Ver. 1
  25. waiting -> activate 25 • waiting script moves to active

    • Fires onactivate • but Not Controller yet Ver. 1
  26. Be a Controller 26 • If there has a chance

    to be controller • Script became controller • Fires oncontrollerchange Ver. 1
  27. Chance to be Controlle ? 27 • Avoid state conflict

    between current controller and next controller • Next page load • call claim() Ver. 1
  28. skipWaiting/claim self.addEventListener('activate', (e) => { console.info('activate', e); // make me

    controller immediately !! e.waitUntil(self.clients.claim()); }); 28 navigator.serviceWorker.register('worker.js') .then((registration) => { return navigator.serviceWorker.ready; }); master.js worker.js
  29. Update SW 29

  30. update() navigator.serviceWorker.register('v1.js') .then((reg) => { reg.addEventListener('updatefound', (e) => { console.info('update',

    e); // v2 found }); return navigator.serviceWorker.ready; }).then((registration) => { setInterval(() => { // update registration.update(); }, 1000); }); 30
  31. update() or reload 31 • reload / call update() fetches

    script again • If script changed(v2), install again • Fires onupdatefound Ver. 2
  32. update() and browser cache 32 • update() hits browser cache

    • But bypass(max-age) it after 24h • Security knowledge from App Cache Cached Ver. 1 Ver. 2
  33. waiting 33 • Installed v2 became waiting (v1) • If

    activate v2 immediatly, call skipWaiting() Ver. 1 Ver. 2
  34. oninstall/onactivate self.addEventListener('install', (e) => { console.info('install', e); // do some

    prepare not affect to v1 // like cache new resouce etc }); self.addEventListener('activate', (e) => { console.info('activate', e); // do some cleanup of v1 // like schema update etc }); 34
  35. waiting 35 • Redundant old controller & oncontrollerchange Ver. 1

    Ver. 2
  36. skipWaiting/claim self.addEventListener('install', (e) => { console.info('install', e); // make me

    active immediately !! e.waitUntil(skipWaiting()); }); self.addEventListener('activate', (e) => { console.info('activate', e); // make me controller immediately !! e.waitUntil(self.clients.claim()); }); 36
  37. 37 When worker works ? • Works even if offline

    • Works even if page not opened • Works even if browser closed
  38. 38 When worker stops ? • Active worker stops anytime

    while no event • Restart when event fired • Save Every Data into Storage (not on memory)
  39. Scope 39

  40. register() with scope navigator .serviceWorker .register('worker.js', { scope: '.' })

    .then((registration) => { return navigator.serviceWorker.ready; }); 40 master.js • Controller controls client in scope • Could register multiple controller in different scope • But only one Controller for Client always
  41. Scope 41 • Browser searches controller for client • Wide

    scope affects deep path • Deep match with path & scope
  42. Scope 42 • If you avoid sw in deep path

    ◦ If-else in controller ◦ Register emtpy SW cache.js cache-push.js empty.js
  43. Service Worker Allowed 43 • /js/worker.js can’t register /foo ◦

    Only /js/* are allowed ◦ Add Service Worker Allowed: “/foo” as HTTP header
  44. Tips 44

  45. On insecure origin 45 $ google_chrome \ --user-data-dir=/path/to/js \ --unsafely-treat-

    insecure-origin-as-secure=http://insecure.example. com • Register SW to insecure origin • For Develop only • But Let’s Encrypt it
  46. tips 46 • Be friend with Chrome Canaly Dev Tools

    • Always Check registration & update • Design Scope Carefully • Maintain Cache Carefully • Never forget save to DB while event lifetime • Basiclly no code outside event handler • Start with Implicit Proxy ◦ Local Implicit proxy: works same w/o sw ◦ Local Orgin Server: generate contents in sw • Push is not only usecase for sw
  47. Finished 47

  48. Jack thanks