DEV Community

Cover image for Virtual DOM in react
Aastha Pandey
Aastha Pandey

Posted on • Updated on

Virtual DOM in react

Why virtual DOM?

To avoid re-creation of elements if possible in real DOM, when one manipulates DOM elements.The Virtual DOM concept can help in efficient DOM manipulation through diffing and reconciliation.

Diffing is a process of comparing the previous virtual DOM to current virtual DOM and changing only those elements which are different.

Note: List items should have a *key attribute to stop recreating the list items that aren't changed.*

Reconciliation is when virtual DOM syncs with real DOM.

Real or browser DOM looks like the one shown below:

Alt Text

Virtual DOM is representation of UI, like real DOM excluding the heavy parts, which is kept in memory as a javascript object.

Virtual DOM looks like the one shown below:

//virtual DOM

const virtualDOM = {
    tagName: 'html',
    children: [
      { tagName: 'head' },
      {
        tagName: 'body',
        children: [
          {
            tagName: 'div',
            attributes: { id: 'root' },
            children: [
              {
                tagName: 'div',
                attributes: { class: 'App' },
                children: [
                  {
                    tagName: 'ul',
                    children: [
                      { tagName: 'li', textContent: 'Tea' },
                      { tagName: 'li', textContent: 'Juice' },
                      { tagName: 'li', textContent: 'Water' },
                      { tagName: 'li', textContent: 'Milk' },
                    ],
                  },
                ],
              },
            ],
          },
        ],
      },
    ],
  };
Enter fullscreen mode Exit fullscreen mode

Suppose there is a list of four items, and you wish to change the child of first list item, then in real DOM that list element will be recreated along with the updated text.

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <script>
      function change() {
        document.getElementById("Tea").innerHTML = "Tee";
      }
    </script>
    <div id="app">
      <ul>
        <li id="Tea">Tea</li>
        <li id="Juice">Juice</li>
        <li id="Water">Water</li>
        <li id="Milk">Milk</li>
      </ul>
      <button id="1" onClick="change()">Change first item</button>
    </div>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

The purple highlighted texts in both the images shown below are recreation.

Manipulating real DOM without using virtual DOM concept

Alt Text

import React from "react";

export default function App() {
  const [name, setName] = React.useState("Tea");
  return (
    <div className="App">
      <ul>

        <li key="Tea">{name}</li>
        <li key="Juice">Juice</li>
        <li key="Water">Water</li>
        <li key="Milk">Milk</li>

    </ul>
      <button id="1" onClick={() => {
        setName("Tee")
      }}>Change first item</button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

If the same thing is done using virtual DOM only the changed child not the list element will be recreated in the real DOM as shown below.

Manipulating real DOM using virtual DOM concept

Alt Text

Top comments (14)

Collapse
 
itachiuchiha profile image
Itachi Uchiha

I think we can write a simple virtual dom function like that. This isn't best but it should work :P

const domSource = [
    {
        tagName: 'div',
        className: ''
    },
    {
        tagName: 'p',
        children: [
            {
                tagName: 'span'
            }
        ]
    }
]


function virtualDom(element, domSource) {



    domSource.forEach(elData => {

        const { tagName } = elData

        const newElement = document.createElement(tagName)

        element.appendChild(newElement);

        const hasChild = elData.children && elData.children.length;

        if(hasChild) virtualDom(newElement, elData.children)
    })

}

virtualDom(document.querySelector("#app"), domSource)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
aasthapandey profile image
Aastha Pandey

Hey! Itachi uchiha
Have you tried to exceute it?
😃

Collapse
 
itachiuchiha profile image
Itachi Uchiha

I didn't. But I'm sure it will work for the first time.

When you run it secondly, probably it will create duplicate elements.

Collapse
 
grahamthedev profile image
GrahamTheDev

Suppose there is a list of four items, and you removed an item or added one, then in real DOM the entire document will be recreated.

I am a little confused, what are we comparing React to in this post? Is this a comparison to an old framework or something as this shouldn't be true in most circumstances.

For example with vanilla JS you would just do document.querySelector('li').remove(); to remove the first list item - that is essentially what React is doing, but after it has diffed the document to work out that is what needs doing.

There is no need to repaint the whole document in any framework I have ever seen, certainly not in vanilla JS?

Collapse
 
aasthapandey profile image
Aastha Pandey

Hi! actually you're right, I re-read my post and got the mistake.
Thanks for pointing it out.

Collapse
 
chrisczopp profile image
chris-czopp

With all the respect, I think Virtual DOM will slowly start vanishing in favour of build-time DOM diffing already provided by SolidJS or Svelete. We might lie ourselves that keeping a copy of an entire DOM tree and re-calling the entire call-stack is more performant. But, the truth is that Virtual DOM is just a tool which has been used to allow declarative UI building and this can be already done without Virtual DOM.

Collapse
 
aasthapandey profile image
Aastha Pandey

Hey! Chris-czopp
Build-time DOM diffing sounds fascinating.
I would like to know more about this diffing, could you write a post on it or elaborate in the comments.
Thanks in advance

Collapse
 
chrisczopp profile image
chris-czopp

It has been already covered quite well, you can take a look at dev.to/t/solidjs

Collapse
 
trunghieu99tt profile image
Trung Hieu Nguyen

After having been working with ReactJS for a while, I still can't get the benefit of Virtual DOM. The biggest benefit that you mentioned on your post is about "fast update" and "partial update". But the point here is updating in real dom is fast too, and after updating on Virtual DOM, you still have to go back to Real DOM to update it. What makes Real DOM slow is that after updating, Real DOM have to re-calculate style, layout (it's called repaint to something like that if I rememeber it correctly), so does Virtual DOM somehow solves that problem? Thanks!

Collapse
 
aasthapandey profile image
Aastha Pandey

Hi! Even I feel the same, I didn't compare the speed of the Real DOM and the virtual DOM, I just tried to explain how virtual DOM works in react and what happens behind the scenes.
It's just that since react has virtual DOM you don't have to update the DOM manually.

Collapse
 
thinhvu profile image
Thinh Vu • Edited

"Virtual DOM is nothing but a copy of real DOM which is kept
in memory as a javascript object."

Feel bad for someone who read this.

Collapse
 
aasthapandey profile image
Aastha Pandey • Edited

Hi, Thinh Vu
If you don't find it correct, would you mind correcting it.
If I don't write article how would I know whether I understand it or not because then only good people like you would be able to correct me.
Thanks in advance

Collapse
 
thinhvu profile image
Thinh Vu

The incorrect part is "a copy of real DOM".

VDOM is not a copy of real DOM, is just a plain javascript object (PJSO) which contains ~30 properties (depend on libraries implementation).

Mean while DOM is a huge object which contains more than 100 properties (included browser specific properties which we don't even need to care about).

FYI, you can console.dir($0) in console window to see DOM properties.

Diffing VDOM tree is faster than the DOM due to the less amount of properties and the time to traversal PJSO tree rather than the DOM tree.

So we'll get the benefit for using VDOM to detect the change (everytime state change and it happen a lot).

It's weird when someone think that update DOM over VDOM is faster than update the DOM. It's totally wrong because we also need to update the DOM after the diffing completed.

Thread Thread
 
aasthapandey profile image
Aastha Pandey

Actually, by copy I didn't mean the exact copy of Real DOM because it's obvious if it would be an exact copy of real DOM then how it could be virtual DOM.

What I forgot to mention was "excluding the heavy parts of real DOM*.

I think you focused more on that copy thing and ignored the rest of the things like I too have mentioned about javascript object, and in the entire post, I didn't mention anywhere that Virtual DOM is faster than Real DOM.

I had already edited the post when you pointed out before you replying to me, try to be soft-spoken and humble, trust me it won't harm.

Thank you so much for that extra knowledge about console.dir($0).