Beyond The Tab: Executing JavaScript Across Browser Contexts @ All Things Open

Beyond The Tab: Executing JavaScript Across Browser Contexts @ All Things Open

Keeping JavaScript from interfering across tabs is great, but what about when a web application wants to share state without a server? You'll leave this talk with enough knowledge to get started with SharedWorkers, ServiceWorkers, and other techniques - and enough wisdom to know when to use them.

2e055eb589fb86174fd268748b0fcd30?s=128

Andrew Dunkman

October 26, 2016
Tweet

Transcript

  1. 2.
  2. 3.
  3. 6.
  4. 12.
  5. 13.
  6. 14.
  7. 18.
  8. 19.
  9. 20.
  10. 25.
  11. 26.
  12. 28.
  13. 30.
  14. 31.
  15. 32.
  16. 33.
  17. 34.
  18. 35.
  19. 36.
  20. 37.
  21. 38.
  22. 39.
  23. 40.
  24. 41.
  25. 42.
  26. 43.
  27. 44.
  28. 46.
  29. 51.
  30. 52.
  31. 59.

    In Out document.cookie = cookieName + "=" + encodeURIComponent(json); var

    regex = new RegExp( "(?:(?:^|.*;)\\s*" + n + "\\s*\\=\\s*([^;]*).*$)|^.*$");
  32. 60.

    In Out Detect document.cookie = cookieName + "=" + encodeURIComponent(json);

    var regex = new RegExp( "(?:(?:^|.*;)\\s*" + n + "\\s*\\=\\s*([^;]*).*$)|^.*$"); setInterval(checkForChanges, pollingInterval);
  33. 68.
  34. 69.

    var tabId = Math.random(); video.addEventListener("play", function () { localStorage.setItem("playing_tab", tabId);

    }); window.addEventListener("storage", function (event) { var isThisKey = event.key === "playing_tab"; var notThisTab = event.newValue !== tabId; if (isThisKey && notThisTab) { video.pause(); } });
  35. 70.

    var tabId = Math.random(); video.addEventListener("play", function () { localStorage.setItem("playing_tab", tabId);

    }); window.addEventListener("storage", function (event) { if (event.key === "playing_tab" && event.newValue !== tabId) { video.pause(); } });
  36. 71.

    var tabId = Math.random(); video.addEventListener("play", function () { localStorage.setItem("playing_tab", tabId);

    }); window.addEventListener("storage", function (event) { if (event.key === "playing_tab" && event.newValue !== tabId) { video.pause(); } }); 9
  37. 72.
  38. 78.
  39. 79.
  40. 80.
  41. 81.
  42. 82.

    $

  43. 83.
  44. 90.
  45. 91.
  46. 92.
  47. 93.
  48. 94.
  49. 95.
  50. 96.
  51. 101.

    @adunkman Service workers essentially act as proxy servers that sit

    between web applications, and the browser and network (when available). … They will also allow access to push notifications and background sync APIs. –MDN
  52. 102.

    @adunkman Service workers essentially act as proxy servers that sit

    between web applications, and the browser and network (when available). … They will also allow access to push notifications and background sync APIs. –MDN
  53. 103.
  54. 104.
  55. 105.

    @adunkman Service workers are a new browser feature that provide

    event-driven scripts that run independently of web pages. –W3C
  56. 106.

    @adunkman Service workers are a new browser feature that provide

    event-driven scripts that run independently of web pages. –W3C
  57. 107.

    @adunkman A service worker is a process which is tied

    to domain events rather than to a browsing context. –me
  58. 111.
  59. 112.
  60. 113.
  61. 114.
  62. 115.
  63. 116.
  64. 117.
  65. 118.
  66. 124.

    Page navigator.serviceWorker.register("sw.js") .then(function (reg) { console.log("success", reg); }).catch(function (err) {

    console.log("fail", err); }); Tab 1 worker.js 1 Tab 2 (old) worker.js 1 (new version)
  67. 127.

    Page navigator.serviceWorker.register("sw.js") .then(function (reg) { console.log("success", reg); }).catch(function (err) {

    console.log("fail", err); }); Worker self.addEventListener("install", function (event) { self.skipWaiting(); });
  68. 128.

    Worker Page navigator.serviceWorker.register("sw.js") .then(function (reg) { console.log("success", reg); }).catch(function (err)

    { console.log("fail", err); }); self.addEventListener("push", function (event) { console.log("message", event); }); self.addEventListener("install", function (event) { self.skipWaiting(); });
  69. 129.
  70. 132.
  71. 134.
  72. 135.
  73. 136.
  74. 137.
  75. 138.
  76. 139.
  77. 148.
  78. 150.
  79. 151.
  80. 152.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  81. 153.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  82. 154.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  83. 155.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  84. 156.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  85. 157.

    Worker self.addEventListener("fetch", function (event) { console.log(event.request.url); event.respondWith( caches.match(event.request) .then(function (response)

    { if (response) { return response; } return fetch(event.request) .then(function (response) { return response; }).catch(function (error) { throw error; }); }) ); });
  86. 160.
  87. 161.
  88. 165.