Still, you can archive significant speed-ups with WebAssembly at some use cases.
For example, I have a hash function library (https://github.com/Daninet/hash-wasm) where I was able to archive 14x speedup at SHA-1 and 5x speedup at MD5 compared to the best JS implementations.
That's exactly the kind of thing I think WASM is good at - small, computationally expensive libraries that are easy to just plug in.
I'm more of a web developer and every time I think "hmm, could I use this to build a webapp?", but quickly shrug it off because it would create a big headache and the JS execution is rarely the bottleneck (and if it is, it's likely developer error and inefficiencies than the language / interpreter).
It's very similar to the Python/C distinction. Python will often drop into C for the use-cases you're describing. However, unlike WASM, Python/C is the wild west:
- The whole CPython interpreter is the "C-extension interface" which means that the CPython interpreter can hardly change or be optimized or else it will break something in the ecosystem (and for the same compatibility reason it's virtually impossible for alternative optimized interpreters to make headway), and because the interpreter is so poorly optimized the ecosystem depends on C extensions for performance. WASM presumably won't have this distinction.
- Without the abysmal build ecosystem that C and C++ projects tend to bring with them, building and deploying WASM applications will likely be pleasant and easy after a few years. Of course, if your WASM is generated from C/C++ then that's a real bummer, but fortunately this should be a much smaller fraction of the ecosystem than it is with C/Python.
Network roundtrips are unavoidable, but WASM could be used to parse a server response and generate custom HTML to use in replacing some portion of the DOM. It would likely be a lot faster than trying to do the same in pure JS, and it would obviate the use of over-complicated hacks like virtual DOM and the like.
No, parsing the response is usually way too fast to make a difference. Generating an HTML string is also usually pretty fast. The slowness happens when you ask the browser to parse that HTML string and generate the appropriate DOM, WASM is not going to get you out of that.
> The slowness happens when you ask the browser to parse that HTML string and generate the appropriate DOM
If you do it right, that step only has to happen once for each user interaction. You can entirely dispense with the need to do multiple edits to the DOM via pure JS.
Forcing the browser to continually parse HTML and generate a new DOM tree, recalculate layout, etc. shouldn't be faster than updating specific nodes than need changes.
Absolutely, it's been kind of incredible progress. But it's still going to be a bottleneck more often than JS execution (in my experience at least).
Not always; I have definitely run into applications where parsing large amounts of data in code is a bottleneck, especially when building large charts. But often.
My general worry is that the performance gains from using some WASM will just get eaten up by the overhead of jump between JS and WASM and having to copy/convert data. You might be able reduce the problem by porting more stuff from the JS side to the WASM side, but then you risks pulling in huge chunks of your app.
JS/WASM calls are fast in V8, and still seem to be improved from time to time (e.g. see: https://v8.dev/blog/v8-release-90#webassembly), not sure about any large data optimizations (TBH I'm not sure what this is about though, because usually one would use JS slices into the WASM heap to avoid redundant copying)
That works if the data is already in the Wasm linear memory and you need to access it from JS. If you have strings (or whatever) in JS, you need to copy them into the linear memory for the Wasm module to use.
And there might be other benefits besides performance. I'd like to use WASM to be able to reuse server side code in languages like Rust or Go in the client, so you don't have to re-implement algorithms and tricky processing code in javascript.
I experimented with this some weeks ago and it is certainly possible.
I had a PoC where my server runs Rust, exposes a JSON Rest API using serde to serialize my Rust structs to JSON. On the web Client I compiled Rust to wasm and used the Reqwest crate (http client that uses Fetch in wasm) to talk to my server, Rust structs are shared between server and client.
For me, the beauty about Rust in this setup, is that cross compiling/crossplatform is builtin into the tooling (Cargo). For example the Reqwest crate compiles down to use the browser Fetch api when running in Wasm, and the same crate on the server uses a native implementation using openssl (or rusttls).
I did something making a game. The game logic runs server side however in order to hide latency the clients also run a WASM copy locally. Then once the server processes their moves they check that everything was in-sync and if not reload with the server state.
(In practice the validation is probably not necessary but doesn't hurt to have).
Yeah, WebAssembly have i64/u64 types as first class citizens unlike JavaScript which should emulate it or use BigInt which drastically slower than native 64-bit types. That's why crypto algorithms got a lot of speed benefits. AssemblyScript also show this. See this:
I'm more of a web developer and every time I think "hmm, could I use this to build a webapp?", but quickly shrug it off because it would create a big headache and the JS execution is rarely the bottleneck (and if it is, it's likely developer error and inefficiencies than the language / interpreter).