[ServiceWorker] Worker-As-A-Service service workers (#744)

After revealing the [`BPG` image-format-decoding](http://flaki.github.io/bpg2jpg/test-sw.html) usecase for service workers both @jakearchibald and @domenic [pointed out](https://twitter.com/domenic/status/639047174563758080) that the use case misses [workers-in-service workers](https://github.com/slightlyoff/ServiceWorker/issues/678) gravely. And that's entirely true, even with ASM.js enabled, and both decompressing and recompressing accomplished in the same Emscriptened (=*fast*) script, we are still blocking the SW thread for these operations.

There is also bit of an issue with the current implementation. Imagine `BPG` becoming a big hit in the near future, and suddenly everyone starts using a (more sophisticated) version of this polyfill to add support for older browsers. That would mean all sites on the internet including in their potentially slim service worker script a ~200KByte JavaScript blob for image file transcoding. That is, the same JS in every single worker.

AFAIK the `importScripts` call supports off-origin script files, so we could theoretically host the lib off a CDN, including it in every service worker from the same location so we could at least save some data traffic and latency on the cached script, but this doesn't feel to me an ideal choice either.

After giving this a little more thought I realized what this service worker *actually* needs is just a service - image-transpilation-as-a-service. Give me a large blob of `BPG` data, I'll give you back a `JPEG`. This idea brings us back to cross-origin service workers/`navigator.connect`, as we could have, say `bpg2jpg.github.io/api/` which has a service worker that accepts post requests with image data, and responds with `JPEG` images. After being referenced for the first time, the service worker would work as a locally running service, in his own thread, accepting requests from all local clients/websites and serving those asynchronously.

I'm not entirely familiar with the current state of cross-origin service workers (I know fall-through requests are happening but I don't think that helps the above usecase), but I remember `navigator.connect` had a prospect something among these lines.

If anyone could chime in regarding the above that would be great.

Also the question that emerges from the above: do we *really* need workers in service workers or what we need is some kind of cross-service worker communication (and reimagining our existing worker-based architecture as service-based architectures)?
Is there a usecase or limitation that would work with workers-in-service-workers, but could not be realistically transposed into a locally run service.

Two issues that come to my mind:
* **Versioning** -  with a central repository we would need to access different versions of the script. With breaking versions this could be solved like any other API out there, e.g. using different entry points (`/api`, `/api2.0`...).
* **Performance** - for larger datasets, transfer overhead could slow things down (big binary datablobs, like image data POSTed and received). I imagine this might be optimized browser-side recognizing local service-worker-to-service-worker requests and optimizing the data transfer, but this could prove to be a bigger issue.

Even if we couldn't throw away workers-in-service workers just yet, I imagine a lot of the apparent usecases could be solved with above approach, and thus workers could be pushed back to a later point in time (I'd certainly imagine that the Mozilla e-mail case could work this way as well, maybe @jrburke can back me up or correct me in this).

---
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/744

Received on Friday, 4 September 2015 19:05:48 UTC