A lot of people have the misconception that writing their app in a lower level language (ex: Rust) that runs in WASM and renders in a <canvas> would be (if nothing else) good for performance
This is… probably… mostly… not the case. Okay it’s not the case.
It’ll be slower.
Unless you’re writing a game. Which you’re probably not if you’re here. Most of the rendering completely you’ve got is gonna be doing basic layout-y stuff
The vast majority of the heavy lifting there is being done by already well optimized HTML/CSS rendering engines
For starters, don’t try to redo the browser’s rendering engine’s job in JS
Your JS code has a lot more overhead than the code running in the browser doing the same layout, painting, compositing, event delegation, etc etc etc work
Next you try WebAssembly. Immediately you run into the problem that it doesn’t have native canvas bindings and you’re paying a significant cost to transfer it over to JS to display it in the canvas. Not great
But WASM will probably get real canvas bindings someday. So let’s ignore that.
It is going to be very costly to ship an entire rendering engine in WASM that has a comparable set of features to HTML/CSS. And WASM on its own is going to set it back a bit
And that doesn’t even begin to get into all the ways your app can be rendered faster by just letting the browser do its job steaming things in parallel. You can’t do that in WASM while you’re waiting for your rendering engine to download.
This doesn’t even begin to get into the fact that most of the tools trying to do this today also rely on building an invisible semantic accessibility tree in the DOM anyways, which gives you the perf hit from both.
So no, WASM + <canvas> is not the death to the DOM/JS/CSS etc. At least not because of some wild performance benefit.
That doesn’t mean WASM or <canvas> are not incredibly useful tools for performance and general utility
Canvas can work great alongside your app’s HTML/CSS to focus on just the little bits that can have huge perf wins
Things that don’t inherit the entirety of the complexity of a browsers rendering engine
My fave example is an emoji picker. But mostly graphics/visualizations
Instead of chasing this though. We should be working towards getting the browser to offload more layout work being done in JS to native code
More native controls
More native control styling
All that’s being worked on
PS: Don’t use Flutter, it’s only feature is “consistency” and it barely delivers that while being a giant middle finger to accessibility
(If you’re not aware, Flutters primary rendering backend for web is exactly this. It renders into a canvas with its own rendering engine, with an opt-*in* invisible semantic tree in the dom just in case you want the minimum viable amount of accessibility)
Side note: I would sooner buy into the idea we might someday have WASM apps rendering DOM than just canvas
Especially if they do the whole server-side render, client-side hydrate thing with lots of code splitting
That still won’t be a JS killer but I can see a case for it