|
The shadow DOM doesn't help at all here, that's mainly about scope and isolation. The (in fairness confusingly named) virtual DOM helps by splitting up writes and reads. The goal when updating the DOM is to do all the reads in one batch, followed by all the writes in a second batch, so that they never interleave, and so that the browser can be as asynchronous as possible. A virtual DOM is just one way of batching those writes together. It works in two phases: first, you work through the component tree, and freely read anything you want from the DOM, but rather than make any updates, you instead build a new data structure (the VDOM), which is just an internal representation of what you want the DOM to look like at some point in the future. Then, you reconcile this VDOM structure with the real DOM by looking to see which attributes need to be updated and updating them. By doing this in two phases, you ensure that all the reads happen before all the writes. There are other ways of doing this. SolidJS, for example, just applies all DOM mutations asynchronously (or at least, partially asynchronously, I think using microtasks), which avoids the need for a virtual DOM. I assume Svelte has some similar setup, but I'm less familiar with that framework. That's not to say that virtual DOM implementations aren't still useful, just that they are one solution with a specific set of tradeoffs - other solutions to layout thrashing exist. (And VDOMs have other benefits being just avoiding layout thrashing.) So to answer your question: the virtual DOM helps because it separates reads and writes from each other. Reads happen on the real DOM, writes happen on the virtual DOM, and it's only at the end of a given tick that the virtual DOM is reconciled with the real DOM, and the real DOM is updated. |
> So to answer your question: the virtual DOM helps because it separates reads and writes from each other. Reads happen on the real DOM, writes happen on the virtual DOM, and it's only at the end of a given tick that the virtual DOM is reconciled with the real DOM, and the real DOM is updated.
I still don't understand why this can't be done (or isn't currently done) by the browser engine on the real DOM.
I'm sticking to the example given: write $FOO to DOM causing $BAR, which is calculated from $FOO, to change to $BAZ.
Using a VDOM, if you're performing all the reads first, then the read gives you $BAR (the value prior to the change).
Doing it on the real DOM, the read will return $BAZ. Obviously $BAR is different from $BAZ, due to the writing of $FOO to the DOM.
If this is acceptable, then why can't the browser engine cache all the writes to the DOM and only perform them at the end of the given tick, while performing all the reads synchronously? You'll get the same result as using the VDOM anyway, but without the overhead.