Hacker News new | ask | show | jobs
by i_s 3398 days ago
It is really how disappointing the options to share data with workers are in the browser.

Combine the limited options options to transfer data quickly, and the limited API available in the worker itself (no version of a DOM, even a gutted one for doing measurements), it is no surprise how few opportunities to use them effectively there are.

When it comes to transferring objects, it is so bad people are resorting to JSON.stringifying messages. [0]

Seems like it would be easy to just add an Immutable Array and Map to the standard library, and let people use that on workers without these silly limitations. What am I missing?

[0] https://nolanlawson.com/2016/02/29/high-performance-web-work...

2 comments

I used web workers extensively in a JS project a little over a year ago, and it was a nightmare. Granted what I was attempting was crazy, but it shouldn't have been as painful as it was.

Basically the "gotchas" are in the browser implementations. Each browser's web worker implementation is a little different, and those little differences (bugs) have huge implications in terms of what you can and can't do. For example: one browser may relay direct worker-to-worker messages via the main thread, so if your main thread is blocked your workers can't talk to each other, and that largely defeats the entire purpose of direct worker-to-worker communication.

Fortunately some of these issues have been fixed since (including that one, if memory serves), but it's slow going. I believe what happened was workers were introduced 5+ years ago, met with little interest initially, and the APIs have rotted for years until recently when interest picked up again, especially since SharedArrayBuffer.

My qualm with SharedArrayBuffer is that it kind of sucks to use in pure JS projects, because you have to serialize/deserialize everything to and from the buffer. With the Emscripten toolchain's pthreads support, as far as I'm aware you just compile your code and the heap lives inside SharedArrayBuffer. You don't have to write boilerplate serialization code, so compared to plain JavaScript it's seamless experience in that regard.

My advice to anyone using web workers in a pure JavaScript project is to use them as their name implies: offloading long-running calculations. If you try to treat them as true threads, you're going to have a bad time. Especially if your inter-worker messaging volume is high and you have frequent interdependent (blocking) calculations.

That said, the work I did was prior to SharedArrayBuffer. For very high-performance projects, it will likely be prudent to use SharedArrayBuffer itself as a messaging medium between workers.

Ios has a ui thread and a separate thread for application logic. React native makes good use of this to make applications silky smooth.

In Web land, the overhead of communication with workers is costly that it makes sense to do things in main thread. Preact had an worker diffing implementation but that was slower.

We once had to unzip on worker and pass to main thread, it was faster just to do it on UI thread.

(I'm the author of the article you cite.)

For the record, Chrome has been working on improving their postMessage performance as of M57 [1], so my benchmark should probably be re-run.

Assuming they end up in the same ballpark as Safari and Edge, the only browser for which stringification would still make sense is Firefox. (And maybe they have improved in the past year too. :))

But a lot of the conclusions from that article came from the fact that non-stringified postMessage perf was so bad in Chrome, which especially impacted performance on Android devices.

[1]: https://twitter.com/cramforce/status/824273332258209792