Also languages like C, C++ or Rust let you exactly define the layout of data on the heap, which is crucial for performance (look up data-oriented-design), and WASM preserves this in-memory layout (since it uses a simple linear heap, like C, C++, Rust, etc... but unlike Javascript, C# or Java). Achieving something similar in a high level language like Javascript would involve mapping all application data into a single ArrayBuffer "pseudo heap", and at that point, it's easier and more maintainable to do the same thing in C (or C++ or Rust).
Having said all that: modern Javascript engines can perform surprisingly well (in general I'm seeing that Javascript performance is underrated, and WASM performance is often overrated - sane Javascript, WASM and native code can all be in the same performance ballpark, but native code usually has the most "optimization potential").
Assemblyscript is unfortunately not that fast (yet?), same as javascript in most cases, also because it uses a garbage collector.
"in general I'm seeing that Javascript performance is underrated, and WASM performance is often overrated - sane Javascript, WASM and native code can all be in the same performance ballpark, but native code usually has the most "optimization potential""
And strong disagree. Javascript is indeed quite fast, but if you use a native compiled wasm libary in the right way (avoiding too many calls to wasm and back) - you will get a worlds difference in performance.
Well yeah, that because each call is basically an "optimization barrier" for the compiler (on both sides of the call), and of course the call itself also adds overhead, although that has been drastically reduced over the years.