Being Reactive - Usage of Virtual DOM and DOM Diffing

Being Reactive - Usage of Virtual DOM and DOM Diffing

It's been a while I am pushing myself to realize the essence of Reactive Programming. Starting with the implementation in Angular and RxJS, later with ReactJs and half a year back with Vuejs, I was in a state to dig more and learn something new about the concept.

This is the first post of a series to explain my journey on Reactive Programming, Virtual Dom, and a cool new Offering that changed the perspective in a big way! Stay Tuned.

How it all started

My initial attempt was to learn about Reactive Programming from the Wikipedia and I was like,

confused.gif Image Courtesy: GIPHY.com

With time, I was introduced to many definitions and explanations. Here are a few that I understood and could connect to:

Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change (The best part from Wikipedia).

Hard? Try this one.

Reactive programming is programming with asynchronous data streams ( Source).

Simple? Here is the most making sense one:

Reactive programming is about managing the Asynchronous Data Flow for your application. It is about tracking values through your application and if the value changes, your application should React!

An Example of Being Reactive

Here is a simple example of your application being Reactive:

reactive.gif

So, what's happening here?

  • A counter has been defined. You as a programmer have defined the dynamic behavior of the counter value at the time of declaration.
  • You click on a button and the counter behaves as it was declared to behave re-actively. As the value changes, the application reacts(Showing Incremented count and the quotes).
  • The application state update must be taken care of by the Framework or library (ReactJs, Vue, etc.) you are using to develop. The usage of Virtual DOM and the concept of DOM Diffing is the key here.

Virtual DOM

Traditionally Framework / Library like, React or Vue allows you to write declarative state-driven code, but it comes with a cost. The browser needs to do lots of extra work to convert those declarative structures into DOM operations. The technique used for doing this is called, Virtual DOM Diffing.

In many frameworks you build your apps using a special render() function. Let's take an example of a basic React component, code inside the render() function:

function GreetingMessage(props) {
  return (
    <div className="greeting">
      {props.greeting}
    </div>
  );
}

Every time your app's state updates (for example when the greeting prop changes), you create a new Virtual DOM. The framework reconciles the new one against the old one, to figure out what changes are necessary and apply them to the real DOM. This reconciliation of Virtual DOM by comparing each of the nodes, attributes, values are called, Virtual DOM Diffing.

The overall cycle looks like this:

Dom-Diff-Cover.png

Virtual DOM Diffing is Costly

You can't apply changes to the real DOM without first comparing the new virtual DOM with the previous one and reconciliation is mandatory. Let us step through the GreetingMessage example mentioned above:

Let's assume the greeting prop changed from Hello, How are you? to Hola como estas.

  1. Both DOM snapshots(old and new) comparison starts by the Framework. In both, the top div node is seen unchanged. Hence the framework can keep the same div node.
  2. The Framework iterates through all the attributes on the old div and the new one to see if anything to be added/removed/modified. For our example, in both cases, we have a single attribute, a className with a value of "greeting". Hence No change to DOM yet.
  3. Now as it sees the element down, it found that the text has changed, so the real DOM needs to be updated now.

If you notice, as the structure of the DOM remains the same, the comparison goes on until Step 3 where the text change was found. This is expensive and it costs the application most when this comparison takes place at the run time on the Browser. The user of our application may pay the penalty of this cost based on the nature and the implementation of the app. Isn't it something to worry about?

Please be assured that I am not picking on any framework/library like Reactjs or any other that provides the mechanism of Virtual DOM computation. These frameworks are fast to manage the cycle to the DOM update. But it is not in the scope of these frameworks to stop programmers from writing bad code. For example, a bad code in react can make the render() method to get called multiple times unnecessarily. If the code is less buggy, we can leverage the potential of Virtual DOM much better way.

But, there is more to it!

As indicated at the beginning, this is the first post of a series. Stay tuned to get the next one.

Hope you liked the start. Please follow me to read my future articles.

Did you find this article valuable?

Support Tapas Adhikary by becoming a sponsor. Any amount is appreciated!