I have an app that has one pretty frequent cpu intensive call (it computes the lcs for diffing). I decided to benchmark a rust wasm bindgen implementation against the js one I was using and found that ironically enough, node did perform better than rust. To be fair to the rust version, I think the JS implementation was slightly better optimized. I then looked into parallelizing LCS, (which is possible) but bindgen and almost all node:rust ports don’t support multithreaded calls, I can think of a myriad of ways to overcome this but not in a browser context. At that point I gave up on worrying about porting to lower level languages for cpu intensive work because if you’re forced into a single threaded context the gains of a memory managed language are going to be trivial at best and add ipc overhead at worse.
The main culprit of poor JS performance in native contexts is almost always bridges and the serialization/deserialization that comes with them. Electron apps don’t really suffer from the bridge problem. While, I’d never claim that JS is as fast as GO or Java (objectively it isn’t), it’s seems equally naive to suggest that using memory managed languages without exploiting multicore is going to lead to significant performance gains in a native app or web app.
I think the real power of wasm is the power of virtualization, it won’t be performance unless web APIs decide to break the single thread paradigm.