DEV Community

Discussion on: Is VDom still faster?

Collapse
 
marzelin profile image
Marc Ziel • Edited

When you write a React component you're writing imperative code that generates declarative code (a description of a view a.k.a VDOM). But what's the value in this?

An app can be thought of as a state machine: you start at 0 and from there you can typically go to any other state and from that state to some different arbitrary state. For each of these states you have to create a UI view that represents a given state.

Doing this naively you'd have to create code that updates the view from all possible state changes. If you have just 0 (initial) + 3 states it gives 3 + 3 * 2 = 9 (n^2) code paths you have to create and maintain.

But you can be smart about it and when there's a change from, let's say, state 3 to state 1, instead of going there directly, you'll go state 3 -> state 0 -> state 1. In other words, when there's a state change you destroy the view for state 3 and start building the view for state 1 from 0. Now you have all possible state changes covered with just 3 (n) code paths.

Unfortunately, destroying and rebuilding the DOM tree at every state change isn't a good idea because DOM is stateful and isn't optimized to work in this manner.

That's where React comes in. With React you need to create a component that can generate a description of a view for any given state and React will take care to efficiently update the DOM from arbitrary state x to arbitrary state y by comparing the descriptions for the view for both states that your component generated.

So, once again: it's not your component code that's declarative in React - it's the code that your component generates. In other words, React is declarative in the sense that React takes declarative description of the view (that your imperative component generates) and instructs DOM to render or update the view so that it matches the description. Reconciliation process can be thought of as a translation layer that takes declarative code and returns imperative instructions required to update the DOM to the described state.

Declarative approach is a must when you want to build a complex UI because otherwise your code would quickly became unmanageable (for just 10 states you'd have 10^2 = 100 possible code paths) even though destroying the view and rebuilding from scratch is obviously slower than smooth transition from one state to the other.

Technically you could destroy and rebuild the DOM on every change (and force browser vendors to optimize for that) but as you mentioned a better way is to optimize code at build time and React team is aware of that:

Additionally, React has been out for about five years, and we want to make sure it stays relevant in the next five years. As Svelte, Angular, Glimmer, and others show, ahead-of-time compilation of components has a lot of future potential. Especially if it’s not limited to templates.

Thread Thread
 
efpage profile image
Eckehard

Engineers have proved that bumblebees can't fly! Luckily the bumblebee does not know this....

Thread Thread
 
lito profile image
Lito
Thread Thread
 
peerreynders profile image
peerreynders

The original statement:

The real goal here is declarative programming.

… an excerpt from Wikipedia

… a style of building the structure and elements of computer programs—that expresses the logic of a computation without describing its control flow.

Given that definition SQL seems like a good example of declarative programming. A statement expressed in Data Manipulation Language "declares" the nature of the data desired while the manner in which it is obtained is left entirely up to the RDBMS engine.

Now based on that example writing components containing imperative code to generate SQL statements (DML) is not declarative programming.

From the React landing page:

Declarative - React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.

So "declarative approach to building UIs" is double speak for "I can't be bothered dealing closely with the actual DOM - ever."

as you mentioned a better way is to optimize code at build time and React team is aware of that

I wouldn't hold my breath - Compiler Optimization Umbrella #9223.

Also Scheduling:

However the freedom to do something like this is why we prefer to have control over scheduling, and why setState() is asynchronous. Conceptually, we think of it as “scheduling an update”.

The control over scheduling would be harder for us to gain if we let the user directly compose views with a “push” based paradigm common in some variations of Functional Reactive Programming. We want to own the “glue” code.

i.e. the design philosophy prefers run time control over compile time commitment.

Thread Thread
 
marzelin profile image
Marc Ziel • Edited

From the React landing page:

Declarative - React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.

So "declarative approach to building UIs" is double speak for "I can't be bothered dealing closely with the actual DOM - ever."

I've just written a post about it here

But you can have stateful function components with hooks and using hooks makes a component impure, right? Technically yes, but in practice not really as I touched upon here.