Why WASM is not the future of Babylon.js
(at least for now)…
We recently got pinged on Twitter regarding a question about WebAssembly (WASM) being the future of Babylon.js.
Here is our response:
Our friends at Three.js had the same answer by the way :)
WASM is a target not a user facing language
WASM is meant to be a way for native developers (mostly C/C++) to compile their project into something that a browser can understand and execute.
You can still read and maybe manually write WASM code as it is text based (the same way you can write byte code instead of writing C# or Java code). It is just terribly inefficient to use it that way. Furthermore to reduce the size most of the time the WASM module are stored in a binary format.
It is named WebAssembly for a reason. It is like assembly code — something really close to the metal where you have to done everything yourself (great power but great responsibilities). Memory management is on you, math functions are on you, string management is on you, etc.
You will find some real world examples here that detail the current situation (spoiler alert: it is not perfect but getting there):
The pspdfkit benchmark using WASM gives me a score of 2928 (the lower the better):
That performance gain is what is mostly appealing for web developers. But unfortunately this is not something we can build a web framework on.
The main reason is that it is not easy (to say the least) to write WASM as it is not really meant to be written by humans. You need to have an engine written in a native language to compile to WASM. A web framework built with TypeScript is not a good source to compile to WASM (yet).
We had a long discussion about it on our repo where we were evaluating the option to use AssemblyScript (a TypeScript to WASM compiler): Port to asm.js/webassembly, is it worth? · Issue #3248 · BabylonJS/Babylon.js (github.com).
The conclusion is that for now we see no good reason to port the entire engine to C++ (immense amount of work, killing all contributions we could get from the community, harder to maintain, etc.) to get the potential performance boost of WASM.
WASM should not be called for small chunk of work
We could argue that some parts of the engine should be written with WASM. Maybe the more compute intensive (like the math library).
This comment in our repo is summarizing it:
For example doing 10000000 adds:
WASM is hard to debug
Because WASM is not easy to read, it it not easy to debug. Chrome recently released some tools to help: Debugging WebAssembly with modern tools — Chrome Developers
But in a nutshell you have to compile your native code with debug symbols to get some debugging support. Clearly not something we expect for a web based framework where debugging is super simple.
WASM could be fat
Because WASM modules needs to provide everything (from memory management to math support) they can quickly become big assets that need to be loaded every time you start your page.
As an example, we are currently working on supporting WebGPU. To do so we need to compile our shaders (written in GLSL) to WGSL and this requires us to load a 3MB WASM module (just remember that the entire babylonjs library is 3MB).
But we still love WASM
That being said we are not haters of WASM. On the contrary we are using it in several areas of Babylon.js (mostly when we want to use existing native code that will do some atomic functions):
- Draco decompression
- KTX2 decoders
- GLSL to WGSL compilation
- Ammo physics engine
- Navmesh and crowd agents
Maybe in the future we will revisit our position if the situation changes but we will always make sure that the experience for web developers is top notch!
David ‘deltakosh’ Catuhe