There's a couple of different sides to the story:- Both WASM and asm.js don't incur JS garbage collector overhead, but it's also possible to write (mostly) garbage-free Javascript by hand.
- Both WASM and asm.js don't use Javascript objects or strings (only numbers), and especially not JS objects where the interior structure changes randomly - which in turn might cause JIT recompiles, but it's also possible to write such 'static' Javascript by hand, especially when using Typescript.
That's basically about the claim 'Javascript performance can be close to WASM'. It's possible to write JS manually which is 'optimization-friendly', but is not necessarily idiomatic JS - the extreme version of this optimization-friendly JS is asm.js, but nobody would want to write that by hand.
Then of course WASM pushes the optimization wall a bit further then what's possible with JS, which may increase the performance gap in very specific situations:
- WASM has native 64-bit integers (JS has BigInt now, but I don't know if they optimize as well under the hood)
- modern WASM has SIMD instructions, which was once an ECMAScript proposal, but has been abandondend in favour of WASM SIMD: https://github.com/tc39/ecmascript_simd
Finally there's the historical angle (e.g. "why does WASM exist in the first place"):
TL;DR:
- with the end of native plugins, Java and Flash in the browser, people were looking for new alternatives to Javascript in the browser
- around 2008(?) Emscripten demonstrated that compiling C/C++ to a subset of Javascript can give surprisingly good performance
- this subset was then formalized into asm.js and browsers started to add specific optimizations for that subset (via "use asm")
- but this JS subset was a dead-end in the long run because requirements for a "Javascript-as-compile-target" clashed more and more with "Javascript-as-programming-language"
- ...so a split was made and WASM was created, from now on, Javascript could focus again to be a programming language, and WASM could focus on being a compile target
I guess that's it...