If you add a wrapper, maybe use a simple heuristic to switch between JSON.parse and fetch. Even something as simple as checking the length of the string may cut it: lower than X? use JSON.parse . Higher? Use fetch.
This doesn't actually succeed (yet?) at avoiding blocking the UI thread while parsing large chunks of JSON. The async API means that browsers could parse JSON from fetch responses on a different thread, but it doesn't mean that they do.
Here's a jsbin experiment that shows that the main thread is blocked while parsing JSON using the author's technique (tested in Chrome 44 and Firefox 41):
sync: total time (blocking): 0.412ms
async: blocking time: 1.822ms
async: total time: 3.943ms
➜ str.length
34527
~34KB json string (10th run):
sync: total time (blocking): 0.569ms
async: blocking time: 0.438ms
async: total time: 2.336ms
~112KB json string (1st run):
sync: total time (blocking): 1.217ms
async: blocking time: 1.036ms
async: total time: 4.818ms
➜ str.length
114745
~112KB json string (10th run):
sync: total time (blocking): 1.658ms
async: blocking time: 0.683ms
async: total time: 4.444ms
Could do with some proper benchmarking by someone who knows more about benchmarking this stuff for real-world usage (i.e.. not me). By the way the 2nd - 10th run results were pretty similar, the amount of time that async function was blocking gradually decreased as it was run more often (I ran the ~34KB tests first).
Maybe it would be better to create a streaming message passing API. e.g. send an object in smaller parts instead of passing JSON and then sending it to the worker and fetch it in parts.
Strange, according to MDN data sent to web workers needs only be deep clone-able[1]. Is this non-standard Gecko behavior?
> aMessage: This may be any value or JavaScript object handled by the structured clone algorithm, which includes cyclical references.
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Worker/post...