Hacker News new | ask | show | jobs
by lelanthran 1053 days ago
I'm gonna apologise in advance for being unusually obtuse this morning. I'm not trying to be contentious :-)

> 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.

1 comments

No worries, I hope I'm not under/overexplaining something!

The answer here is the standard one though: if you write $FOO to DOM, then read $BAR, it has to return $BAZ because it always used to return $BAZ, and we can't have breaking changes. All of the APIs are designed around synchronously updating the DOM, because asynchronous execution wasn't really planned in at the beginning.

You could add new APIs that do asynchronous writes and synchronous reads, but I think in practice this isn't all that important for two reasons:

Firstly, it's already possible to separate reads from writes using microtasks and other existing APIs for forcing asynchronous execution. There's even a library (fastdom) that gives you a fairly easy API for separating reads and writes.

Secondly, there are other reasons to use a VDOM or some other DOM abstraction layer, and they usually have different tradeoffs. People will still use these abstractions, even if the layout thrashing issue were solved completely somehow. So practically, it's more useful to provide the low-level generic APIs (like microtasks) and let the different tools and frameworks use them in different ways. I think there's also not a big push for change here: the big frameworks are already handing this issue fine and don't need new APIs, and smaller sites or tools (including the micro-framework that was originally posted) are rarely so complicated that they need these sorts of solutions. So while this is a real footgun that people can run into, it's not possible to remove it without breaking existing websites, and it's fairly easy to avoid if you do run into it and it starts causing problems.