Skip to content

Instantly share code, notes, and snippets.

@wanderview
Last active October 14, 2015 19:09
Show Gist options
  • Save wanderview/4f0f1bbf8d874842a920 to your computer and use it in GitHub Desktop.
Save wanderview/4f0f1bbf8d874842a920 to your computer and use it in GitHub Desktop.
PoC to extend service worker lifetime past end of fetch event by (ab)using postMessage()
<html>
<head></head>
<body>
<script>
navigator.serviceWorker.addEventListener('message', function(evt) {
if (evt.data === 'CALL ME') {
navigator.serviceWorker.controller.postMessage('RING RING');
}
});
navigator.serviceWorker.register('sw.js');
</script>
</body>
</html>
function doSlowWorker() {
// do something that takes a long time and return a promise
// that resolves when its done
return caches.open('big').then(function(cache) { cache.addAll(hugeList) });
}
self.addEventListener('message', function(evt) {
if (evt.data === 'RING RING') {
evt.waitUntil(doSlowWork());
}
})
self.addEventListener('fetch', function(evt) {
evt.respondWith(Promise.all([
fetch(evt.request),
self.clients.matchAll()
]).then(function(results) {
var response = results[0];
var clientList = results[1];
// We would do our slow work here, but we don't want to block the fetch
// evnt response and we can't safely do it past the end of .respondWith().
// Instead, ask the document to postMessage() us so we can do the slow
// work in a separate .waitUntil(). This will not block the fetch
// event processing.
if (clientList.length > 0) {
clientList[0].postMessage('CALL ME');
}
return response;
}));
})
@wanderview
Copy link
Author

Further correction, you cannot call evt.waitUntil() after the original event handler has returned. So you have to do something like:

self.addEventListener('fetch', function(evt) {
  evt.waitUntil(new Promise(function(resolveWaitUntil) {
    evt.respondWith(fetch(evt.request).then(function(response) {
      resolveWaitUntil(doSlowWork());
      return response;
    }));
  }));
}));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment