Last active
October 14, 2015 19:09
-
-
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()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
})); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Further correction, you cannot call
evt.waitUntil()
after the original event handler has returned. So you have to do something like: