The WASM instruction set is a tiny fraction of the size and complexity of the JVM and CLR instruction sets. One of WASM's primary design goals was to be able to prove safety and soundness properties for the language spec from the very beginning, and they've accomplished that [1]. Subjectively, I'd also argue that it is a much cleaner and more regular instruction set compared to JVM/CLR.
Because it has a lower level of abstraction than JVM/CLR (which, for example, have a built-in notion of what an "object" is, and every other language that you compile to it must have its own semantics shoehorned into that), WASM was able to become a good target for C, C++, and Rust.
The ultimate promise of WASM is that (given the right bindings) you can bring any C/C++/Rust codebase into the browser. E.g. see their demo of Doom running in the browser, utilizing WebGL bindings.
Because it has a lower level of abstraction than JVM/CLR (which, for example, have a built-in notion of what an "object" is, and every other language that you compile to it must have its own semantics shoehorned into that), WASM was able to become a good target for C, C++, and Rust.
The ultimate promise of WASM is that (given the right bindings) you can bring any C/C++/Rust codebase into the browser. E.g. see their demo of Doom running in the browser, utilizing WebGL bindings.
[1] https://www.cl.cam.ac.uk/~caw77/papers/mechanising-and-verif..., explainer video https://youtu.be/zsPVbmEPTlA