Service Worker

Service Worker

The service worker API gives you the control of the http request! I show you how you can create websites with service workers and the offline first approach that are almost equivalent to native apps.

52a875784c4e4ce4fc57ee28bd190dfe?s=128

Pascal Helfenstein

July 06, 2016
Tweet

Transcript

  1. Service Worker

  2. $WHOAMI I am Pascal Helfenstein nicam

  3. What is a Service Worker?

  4. None
  5. What is it? • javascript runtime in a separate thread

    • controls multiple pages • interception and modification of requests & cache • can run without open tab • is activated by the browser whenever necessary
  6. Prerequisite • service-worker & registrator on same origin • https

    only (except localhost) • doesn’t have DOM access • downloaded every 24 hours (on request) • lot’s of promises (.then().catch())
  7. None
  8. caveats • first run doesn’t have a worker* • worker

    gets switched once all tabs with the old worker have been closed • you have to write cache upgrade / clear scripts • can be terminated at any time
  9. index.js if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js', { scope: '/'

    }).then(function(reg) { console.log('Yey!', reg); }).catch(function(err) { console.log('Boo!', err); }); }
  10. basic sw.js self.addEventListener('install', function(event) { // Do cache your stuff!!!

    }); self.addEventListener('activate', function(event) { // Clean up old things!!! });
  11. demo #1 setup le backend le frontend t request response

    register() (web-)socket.emit() $ 3PO! come in 3P0! $ 3PO! come in 3P0! $ 3PO! come in 3P0! $ 3PO! come in 3P0!
  12. Demo 1

  13. None
  14. this.addEventListener('install', function(event) { event.waitUntil(self.skipWaiting()); }); this.addEventListener("activate", function(event) { event.waitUntil(self.clients.claim().then(function ()

    { importScripts('/socket.io/socket.io.js'); var socket = io.connect('http://localhost:3000', { jsonp: false }); setInterval(function () { socket.emit('timer',"3PO!, come in 3P0!"); }, 3000); })); }); sw.js
  15. gotchas • the service worker won’t be running all the

    time • chrome will spin it up when necessary
  16. demo #2 setup le backend le frontend t request response

    register() && activate() index.html index.html index.html
  17. Demo 2

  18. None
  19. cache stuff up front this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) {

    return cache.addAll([ '/', '/index.html', '/images/offline.jpg', '/index.js' ]); }) ); });
  20. intercept requests this.addEventListener('fetch', function (event) { return event.respondWith(caches.match(event.request) .then(function(response) {

    return response || fetch(event.request); }).then(function(response) { caches.open('v1').then(function(cache) { cache.put(event.request, response); }); return response.clone(); }).catch(function() { return caches.match('/images/offline.jpg'); })); });
  21. gotchas • Cleanup your old caches during activation • remember

    all the possible cache versions a client can have • split page cache and asset cache • have different fallbacks for different types of files • fetch doesn’t send cookies by default
  22. demo #3 setup le backend le frontend t request response

    register() && activate() && subscribe() $ curl http://GCM push push spinUp() && receiveMessage()
  23. Demo 3

  24. None
  25. index.js navigator.serviceWorker.register('/sw.js', { scope: '/' }) .then(function(reg) {}) .catch(function(error) {

    console.log('Registration failed with ' + error); }); navigator.serviceWorker.ready.then(function (reg) { reg.pushManager.subscribe({userVisibleOnly: true}) .then(function(sub) { console.log('endpoint:', sub.endpoint); }); });
  26. sw.js this.addEventListener('push', function(event) { console.log('Push message received', event); var title

    = 'The empire needs you!'; event.waitUntil( self.registration.showNotification(title, { body: 'Join the dark side', icon: 'images/trooper.jpg', tag: 'my-tag' })); });
  27. demo #4 setup le backend le frontend t request response

    register() postMessage() postMessage()
  28. Demo 4

  29. index.js var registration; navigator.serviceWorker.register('/sw.js', { scope:'/' }).then(function(reg) { navigator.serviceWorker.ready.then(function(reg) {

    registration = reg; }); }); navigator.serviceWorker.onmessage = function(event) { console.log("Got reply", event.data); }; function sendMessageToWorker() { registration.active.postMessage({ text: "Hi!" }); }
  30. sw.js this.addEventListener('message', function (event) { console.log("event.data"); // Here's your data

    event.source.postMessage("Woop! (via source)"); // OR clients.matchAll().then(function(clients) { for (var client of clients) { client.postMessage("Whoop! (via client api)"); } }); });
  31. Browser Support

  32. The Future • Background Sync • schedule a worker to

    spin up periodically • Geofencing • trigger a worker at certain locations
  33. Questions?

  34. liip.to/serviceworker