It does, but the main speedup comes from using WebGL instead of Canvas2D. Sadly, Canvas2D is still as slow as it ever was and I really wonder why.
Years back I wrote a standalone Canvas2D implementation[1] that outperforms browsers by a lot. Sure, it's missing some features (e.g. text shadows), but I can't think of any reason for browser implementations needing to be _that_ slow.
For things missing/hard in WebGL, is it performant enough to rely on the browser compositor to add a layer of text, or a layer of svg, over the WebGL?
I have some zig/wasm stuff working on canvas2D, but rendering things to bitmaps and adding them to canvas2d seems awfully slow, especially for animated svg.
Ah man, I'm still looking for a general canvas drop in replacement that would render using webgl or webgpu if supported. Closest I've found so far is pixi.js, but the rendering api is vastly different and documentation spotty, so it would take some doing to port things over. Plus no antialiasing it seems.
You don't need multithreading to get concurrent asset streaming, a completion callback or async-await-style code will work too (after all, that's how most Javascript web games load their assets "in the background"). Also, browsers typically restrict concurrent download streams to about 6 (the exact number is entirely up to the browser though) - so you can have at most 6 asset files 'in flight'. In the end you are still limited by the user's internet bandwidth of course.
None of that worked out of the box, and we also spent most of the loading time CPU bound, processing the individual assets after they arrived over the wire. That was a blocking, non-async operation.
Then the next question is why your asset formats require such heavy processing after loading. Normally you'd convert any data into custom engine formats in an offline step in the asset pipeline so that the files can be dumped directly into memory ready for the engine (and 3D API) to be used without an expensive deserialization process.
FWIW, POSIX style multithreading in WASM is supported everywhere for a while now again (it was disabled after Spectre/Meltdown) but is locked behind special COOP/COEP HTTP headers for security reasons (so you either need to be able to configure the web server to return those headers, or use a service worker to inject the headers on the client side.