There is probably a good reason popular frameworks insist on using it though.
- historically, manipulating the DOM directly was slow (in WebKit?) so working on a virtual one made sense
- The idea writing a compiler like Svelte which does the heavy lifting at compile time was not there, or was dismissed for some reason (the React developers might have decided that having a reactive model like Svelte, with the need to tweak JS's semantic a bit - where assigning variables trigger stuff - was not great, or they didn't want this JS/HTML separation)
And then you are stuck with your model for compatibility reasons. React cannot get rid of its virtual DOM without breaking everyone.
Since the VDOM runs fast in Node, you can execute your tests quickly in Jest. But since no real browser are running on Node, the value of this is perhaps questionable.
The browser can get a performance boost via serverside rendering and again it comes in handy that the VDOM runs fast in Node. But perhaps this solves a problem that the VDOM has caused, because React loads slowly and renders the slowest [1].
You can run the VDOM in Android and on iOS via React Native and this is all well, but the VDOM is holding the web back because we have come to expect all this from technologies such as Web Components that might load fast and render fast by virtue of not relying on it.
The virtual DOM is modelling the DOM, but the DOM comes with a model out of the box, it's called the Document Object Model and it is always in sync with the view without any constant performance tweaks. Asynchronous rendering can fix it until batched rendering solves it for good. But these are opposite rendering strategies! We are simply going in circles now.
A lot of the myths around the virtual DOM can be explained by unwillingness to learn the native API and we are mostly dealing with the fallout now. It's the same with CSS. Sorry for the rant and the abuse of your comment.
[1] https://twitter.com/championswimmer/status/14865018568345845...
VDOM is to DOM as Emacs buffer is to terminal display.
Updating the terminal display was historically slow, so there's an algorithm inside Emacs to take the buffer state, diff it against the previous state, and compile a list of terminal commands (escape sequences) that represent a minimal transition between the two states. Famously, it was marked with an ASCII art skull and crossbones in the comments of the source code.
The VDOM is there for the same reason: provide a fast way to minimize the cost of slow DOM transitions.
Diffing with real DOM is slow, majority of vdom libraries aren't diffing with real DOM. As an author of a "vdom" library, I don't like to think about "reconciler" as a diffing algorithm because it is a useless constraint, I like to think about it as a some kind of a VM that uses different heuristics to map state to different operations represented as a tree data structure.
> What I wonder is whether the reason for virtual DOM is really just historic, is there anything else that has caused its persistence other than inertia?
As a thought experiment try to imagine how would you implement such features:
- Declarative and simple API
- Stateful components with basic lifecycle like `onDispose()`
- Context API
- Components that can render multiple root DOM nodes or DOMless components
- Inside out rendering or at least inside out DOM mounting
- Conditional rendering/dynamic lists/fragments without marker DOM nodes
Here are just some basics that you will need to consider when building a full-featured and performant web UI library. I think that you are gonna be surprised by how many libraries that make a lot of claims about their performance or that "vdom is a pure overhead" are actually really bad when it comes to dealing with complex use cases.
I am not saying that "vdom" approach is the only efficient way to solve all this problems, or every "vdom" library is performant(majority of vdom libraries are also really bad with complex use cases), but it is not as simple as it looks :)
That's true, but you need to read a lot from the (V)DOM when diff'ing. Which was said to be slow with the read DOM. I don't know to which extent, and I've read it's not true anymore.
I don't think the diff'ing is done with the real DOM, but between two VDOMs. No?
Anyway, I personally find this approach heavy and like more how Svelte patches the DOM instead of computing a diff.