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

Service Worker registration & lifecycle

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

Jxck

May 18, 2016
Tweet

More Decks by Jxck

Other Decks in Technology

Transcript

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

    View Slide

  2. ● id: Jxck
    ● github: Jxck
    ● twitter: @jxck_
    ● blog: https://blog.jxck.io
    ● podcast: http://mozaic.fm
    ● Love: music
    Jack

    View Slide

  3. mozaic.fm ep17
    3
    Service Worker w/ @kinu, @nhiroki_
    http://mozaic.fm/post/117004083098/17-service-worker

    View Slide

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

    View Slide

  5. Todays Talk
    5

    View Slide

  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

    View Slide

  7. Service Worker
    7

    View Slide

  8. Workers class Hero
    8
    ● Service Worker (got back together)
    ● Shared Worker
    ● Web Worker
    ● App Cache (broke up)

    View Slide

  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

    View Slide

  10. Architecture
    10

    View Slide

  11. 11
    Architecture

    View Slide

  12. 12
    Controller/Client
    ● Controller controls Client
    ○ Client = Window
    ○ Controller = Service Worker

    View Slide

  13. 13
    Event with Client
    ● Controller hooks HTTP request from Client
    ● Controller talks with Client via message

    View Slide

  14. 14
    Event with Network
    ● Controller hooks push from network
    ● Controller hooks change from offline -> online

    View Slide

  15. 15
    websocket
    ● Controller doesn’t hooks client WebSocket
    ● Controller also talks WebSocket

    View Slide

  16. 16
    worker/db
    ● Controller also Use WebWorker / IndexedDB
    ● No LocalStorage because Sync I/O
    ● Separate Context between Client

    View Slide

  17. 17
    cache
    ● Client/Controller has Cache API
    ● Before browser cache
    ● Means fetch from SW hits browser cache

    View Slide

  18. 18
    Architecture

    View Slide

  19. Lifecycle
    19

    View Slide

  20. Lifecycle
    20

    View Slide

  21. Install SW
    21

    View Slide

  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

    View Slide

  23. register() -> oninstall
    23
    ● Browser fetches
    script
    ● Install it
    ● Fires oninstall
    ● Prepare cache or
    migrate schema
    Ver. 1

    View Slide

  24. installed -> waiting
    24
    ● Installed script moves to waiting
    ● Waiting waits to be active
    ● If no active script available, through to active
    Ver. 1

    View Slide

  25. waiting -> activate
    25
    ● waiting script moves to active
    ● Fires onactivate
    ● but Not Controller yet
    Ver. 1

    View Slide

  26. Be a Controller
    26
    ● If there has a
    chance to be
    controller
    ● Script became
    controller
    ● Fires
    oncontrollerchange
    Ver. 1

    View Slide

  27. Chance to be Controlle ?
    27
    ● Avoid state conflict
    between current
    controller and next
    controller
    ● Next page load
    ● call claim()
    Ver. 1

    View Slide

  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

    View Slide

  29. Update SW
    29

    View Slide

  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

    View Slide

  31. update() or reload
    31
    ● reload / call update() fetches script again
    ● If script changed(v2), install again
    ● Fires onupdatefound
    Ver. 2

    View Slide

  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

    View Slide

  33. waiting
    33
    ● Installed v2 became waiting (v1)
    ● If activate v2 immediatly, call skipWaiting()
    Ver. 1
    Ver. 2

    View Slide

  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

    View Slide

  35. waiting
    35
    ● Redundant old controller & oncontrollerchange
    Ver. 1
    Ver. 2

    View Slide

  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

    View Slide

  37. 37
    When worker works ?
    ● Works even if offline
    ● Works even if page not opened
    ● Works even if browser closed

    View Slide

  38. 38
    When worker stops ?
    ● Active worker stops anytime while no event
    ● Restart when event fired
    ● Save Every Data into Storage (not on memory)

    View Slide

  39. Scope
    39

    View Slide

  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

    View Slide

  41. Scope
    41
    ● Browser searches controller for client
    ● Wide scope affects deep path
    ● Deep match with path & scope

    View Slide

  42. Scope
    42
    ● If you avoid sw in deep path
    ○ If-else in controller
    ○ Register emtpy SW
    cache.js
    cache-push.js
    empty.js

    View Slide

  43. Service Worker Allowed
    43
    ● /js/worker.js can’t register /foo
    ○ Only /js/* are allowed
    ○ Add Service Worker Allowed: “/foo” as HTTP header

    View Slide

  44. Tips
    44

    View Slide

  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

    View Slide

  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

    View Slide

  47. Finished
    47

    View Slide

  48. Jack
    thanks

    View Slide