WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
This discussion on Three.js + WebAssembly is not limited to functional programming rather let us discuss all findings related to Three.js + WebAssembly.
So curious to hear about what you have discovered and/or where you see Three.js + WebAssembly in the next 5 years!
What I donāt like about WebAssembly is the fact that your code base is split up into different languages. You can easily see this at the demo of the blog post. So you move away from a unilingual approach (just JavaScript) and start to develop with very technical, compiled programming languages like C/C++ or even Rust (a systems programming language). From my point of view, that makes web development more complicated.
I can understand when a whole software component like a physics engine is encapsulated as a WebAssembly module (especially since you have a better performance). But Iām still not a fan of this architectureā¦
Why do you draw a line at a whole physics engine, what makes this an atomic part in your view of the world? Why not an octree, or a raycaster, or an octree based raycaster?
Not worthy of a discussion? I think itās a good example. There are lotās of internals that most people donāt want to touch, but would prefer if they were as performant as it can get.
As @Mugen87 responded with indeed was an example, wondering if others in the community of Three.js being used with WebAssembly in other ways? Apparently this isnāt happening as much as I had thought. Was only curious. Thanks for everyone(s) input so far!
Iām super curious about this topic but it is indeed intimidating, I tried to get started once and didnāt make much progress. I can definitely think of a use where more optimized code would help a lot.
I tried to use wasm a little a few months ago, but found the whole setup overly complex andāfranklyānot worth the effort at the time (and at that time, not all browsers were shipping with support). Iāve maintained a passing interest since then, but as of right now I donāt feel compelled to leave the pure JavaScript environment.
Why do you draw a line at a whole physics engineā¦ why not an octree, or a raycaster, or an octree based raycaster?
For me thereās a line because compiling, testing, and deploying WASM is currently a pain. Youāll probably have to write bindings for every method you expose. Also, the compiled binary size tends to be much larger than the JS equivalent. For small simple modules, thatās not (yet) worth it. Maybe that will change someday.
I think itās just limitations in the current tooling, Iām optimistic in the long run. There may always be a certain amount of size overhead on a WASM binary that would make it less practical for very small modules, but Iām only guessing.
I donāt know that itās actually wasm's fault. This is just the next iteration of feature creep on the web.
Where this could become really powerful is if we dropped the idea of embedding this stuff into HTML, and wrote entire applications around wasm, with full browser support. If youāre going to write an app, make it as performant as possible via wasm. If youāre just creating documents, use HTML.
(An example of this is running APK files in Chrome. Only written in a web-native language instead.)
My interest for now is access to some of the popular native libraries already used in gamedev. I have no interest in writing more native code myself. But yeah, Google Earth is an example of a complete application where that could make sense ā currently it uses Chrome Native Client, but theyāve said theyāre working toward using WASM instead.
I think WebAssembly is a very interesting technology. Beside the runtime performance promise WebAssembly makes I want to highlight another cool feature.
Parsing and interpreting WebAssembly is much faster than with JavaScript and the parsed and compiled result can be stored into IndexedDB. We use WebAssembly in production and cache it into IndexedDB. This gave us a huge boost on app start up. The slowest thing in our app start up time is still the download and parsing of Three.js. Itās not too bad but on low end devices you can really feel the pain of parsing and compiling JavaScript. So I think WebAssembly could be interesting. Furthermore it would be great if tree-shaking and deadcode elimination would work better with Three.js to get the file size down but thatās another topic
memory allocation wasnāt an easy task (has to be done at the init step, memory grow at runtime is expensive of course, malloc doesnāt work out of the box
if you have to pass data between JS and wasm at each render frame (I guess big arrays if weāre talking about three.js) I donāt know how efficient this runs
WASM will be of great use for specific intensive taks which can be optimized this way, but it shouldnāt be expected as a replacement for JS, rather as for what i just mentioned and providing a interface for other languages, or alternative in the future.
Itās already widely used for cryptominers, utilizing as much as possible out of your device
V8 is actually very powerful and will also compile to machine code where itās possible. I will also mainly make use of it for processing tasks. JS can be heavily optimized too, iāve seen libraries with rather bad practice making code unoptimizable, having exception code in a per-frame manner, allocating and dropping memory/objects frequently, or just an architecture which could be solved more efficiently. Some statements, invokations or allocations might seem small, but the entireness counts and how often things get invoked.
For THREE i would be already happy for now having finally offscreen canvas support in all browsers.
I havenāt done a whole lot with it, yet, but this has recently become a very interesting topic to me. Using something like Rust to implement really performance-bound operations like parsing, raycasting, or other math operations seems like a really good use case and with new tooling itās gotten a whole lot easier to integrate web assembly with javascript. In Parcel, for example, itās as easy as just including the .rs file:
import { add } from './add.rs'
console.log(add(2, 3))
There are also utilities that make it a lot easier to pass data between Javascript and Rust, as well.
Iāve recently ported a contouring algorithm based on octrees to WASM, and the performance gain was rather small, doesnāt mean WASM/the compiler will or has improved, iāll definetly will put my hands on it again, but i donāt expect a too big difference.