Create your own virtual DOM to understand it (Part 2)
Tags: virtualdom, reconciliation, javascript, learnreactjs
Published: 2018-07-29 16:19:55

---
title: Create your own virtual DOM to understand it (Part 2)
published: true
tags: virtualdom,reconciliation,javascript,learnreactjs
cover_image: https://thepracticaldev.s3.amazonaws.com/i/vj45wm9py5u4duy9br70.png
canonical_url: https://aibolik.com/blog/create-your-own-virtual-dom-to-understand-it-part-2
---

_This article is the continuation of_ [_first part_](https://dev.to/aibolik/create-your-own-virtual-dom-to-understand-it-part-1-3g4e)_(so you better read first part too :), where we learnt how to create virtual nodes with JSX-like function_ **_hyperscript_** _and render them. In this part we will implement “_ **_diffing” algorithm_** _of virtual DOM, that is the main advantage of it._

_Originally, I was inspired by the talk of_ [_stefan judis_](https://medium.com/u/c3a0319fab53) _at Web Rebels 2018, so feel free to take a look at it [here](https://youtu.be/kghSjWmNJyQ).

Okay, we have a simple function component that renders dynamic component. Let’s make it a bit complex by introducing its own state and converting it into class with render method. Also we can separate out new **_People component,_** that will responsible for rendering only list of emojis. Here how it will look like after:

![](https://cdn-images-1.medium.com/max/1024/1*gP5nb4zbPqgKgwtTNWdneA.png)<figcaption><strong>People component</strong> that renders list of emojis given in its properties</figcaption>

Nothing special with this component: it just renders list of items that is given in its props. **Note** : we introduced render method here — it actually creates virtual DOM that we use to render real DOM. And here is how our **_App component_** will change:

![](https://cdn-images-1.medium.com/max/1024/1*23EwA0oCCuzbjJvBpM2RTQ.png)<figcaption><strong>App component </strong>turned into class component</figcaption>

Two things to mention here:

1. We set its state in its constructor and create _timer,_ that updates its state every 1 second(1000ms)
2. We call setState method to update its state.

You can find what does setState method in [React’s documentation](https://reactjs.org/docs/faq-state.html#what-does-setstate-do). We will implement almost the same functionality here — update its **state** object and **make our component to re-render.** Of course React’s implementation is not that trivial, it makes bunch of optimizations on top of it, but come on, we are just building it :)

Since the setState is the method that every function will call, it makes sense to create an _abstract class_ that implements it. When you write class MyApp extends React.Component in React you are _inheriting_ the [**Component**](https://reactjs.org/docs/glossary.html#components) class and can use its methods. Okay, let’s scratch our simple Base Component class:

![](https://cdn-images-1.medium.com/max/858/1*D5-dNjonvaqEbQC98iUt9A.png)<figcaption><strong>Base Component </strong>implementation</figcaption>

Basically, we just initiate our component with props and state fields and implement setState method that basically rewrites our state and calls **renderComponent** with itself in its parameters. I’ll explain it now, but first of all let’s make changes to our components:

![](https://cdn-images-1.medium.com/max/716/1*eKQkT7QW7w98peWRoGDFLw.png)<figcaption>Changes to our components</figcaption>

Okay, now we have our **App** and **People** components updated I’ll try to explain what **renderComponent** should do.

1. It grabs the old base(current DOM before change that is saved in component.base)
2. Renders virtual DOM — that we can get from _component.render_ method and saves it into _component.base._
3. Replaces the old child with the new one

Here it is:

![](https://cdn-images-1.medium.com/max/1024/1*ECgKa89HTXvXDMrIghlilg.png)<figcaption><strong>renderComponent </strong>function implementation</figcaption>

> I’ve added parent parameter, to that we could use parent.appendChild when we render the root component first time.

One little change to make it perfect is to change a little bit renderNode function. Remember how it looked before:

![](https://cdn-images-1.medium.com/max/800/1*RxplN3cdbxAPc8Qr5P-vUQ.png)<figcaption><strong>renderNode </strong>before</figcaption>

It only handles DOM elements, but actually we have something like this in our **_App component’s_** render_ _method **_:_**

```
return h('div', { class: 'app' },
 h('h1', null, 'Simple vDOM'),
 h(People)
 )
```

As you can see **nodeName** can take not only string values, but also another component/function to render, in our case this is **_People component_**. We need to make sure we handle them properly — basically we need to initiate the component, render it and do this with all of its children. Here is our updated renderNode implementation:

![](https://cdn-images-1.medium.com/max/1024/1*udGX7_pc2dUa3vVwRvyVlw.png)<figcaption>updated <strong>renderNode </strong>function</figcaption>

That’s it about rendering! Now our app works perfectly: any state change will cause app to re-render — as a result every child element/component will be updated. To leverage from this approach let’s move update operation in our application from **_App component_** to **_People component_** _(remove constructor from App and write it inside People)_ **_:_**

![](https://cdn-images-1.medium.com/max/1024/1*suVzr44RaWNPduSMVh1t9Q.png)<figcaption><strong>constructor</strong> of People component</figcaption>

And update render method of People from this: return h('ul', null, ...props.list.map(item =\> h('li', null, item))) to this return h('ul', null, ...state.list.map(item =\> h('li', null, item)))

Now only **_People component_** will be re-rendered when its state updates. Compare these GIFs:

![](https://cdn-images-1.medium.com/max/480/1*OD2VWhF04kXUvHBEdRvVCA.gif)<figcaption>Application re-render <strong>before</strong></figcaption>

![](https://cdn-images-1.medium.com/max/480/1*1x8MWMqh2HCv4yg8oEjYLg.gif)<figcaption>Application re-render <strong>after</strong></figcaption>

As you can see only the list updates, while the headline(Simple vDOM) does not re-render. Now we made our components **Autonomous.**

> **Note 1** : I’ve changes a bit styles: displayed items in **flex** row, so that adding new items will not cause reflow.

> **Note 2:** To see which parts of the website re-render you can enable **Paint flashing** in Chrome Dev Tools -\> More(… icon)-\> More tools -\> Rendering)

### Diffing algorithm

Well, it looks more like _React-ish_ but re-rendering whole app when we just add a new item to the list is awful. Now it’s time to introduce “ **Diffing” algorithm** that will make our application more powerful.

In our case, we can just naively check if there are any new items in new virtual Node, and if there are any, we will just append it. So let’s start implementing it step by step. First of all, if there is no DOM provided, we just want render our virtual node and append it to the parent:

![](https://cdn-images-1.medium.com/max/812/1*8lZ2fUQEgnjgfFZvNL4YFg.png)<figcaption>Render our app and append it to the parent, if there is no DOM to compare</figcaption>

This is applicable for the _first run — _where there is no DOM rendered yet, and the only place where we give _parent_ in its parameters. So we can use it for initial rendering, here how we will do it:

![](https://cdn-images-1.medium.com/max/952/1*4gZn82zKuRjhrG1k2V3XFQ.png)<figcaption>Rendering app first time</figcaption>

Okay, now we rendered our app, the **_People component_** will update its state after 1 second(remember the _timer_ we set?). That will cause our renderComponent to be called, so it will also be changed:

![](https://cdn-images-1.medium.com/max/1024/1*WDNSeZ6pk67WgR256eTB6A.png)<figcaption>updated <strong>renderComponent</strong></figcaption>

Firstly, we create the virtual DOM with component.render method, then we just compare it with its current DOM state(that we saved in component.base field), and save the result of **diff** in it again. So our **diff** function should check if there are any new child, and in case it is true, we just _append_ it. Here how it could look like:

![](https://cdn-images-1.medium.com/max/1024/1*wEA0oTjVUZPluaaaqYzSHg.png)<figcaption>Simple diffing that checks for new children</figcaption>

That’s it, we made it! Now take a look how it looks in our 3rd iteration:

![](https://cdn-images-1.medium.com/max/480/1*IdRJUrYBPB7rl61Ga8ZK0A.gif)<figcaption>Re-rendering with diffing algorithm</figcaption>

As you can see the whole application and list do not re-render. Only the new child is added to list.

This is just a simple example with simple “_diffing” algorithm,_ but _hopefully_ it will **make sense for those who are new to these concept** _._ It can not be compared to what React does. Here is just a few things what is there in [React’s diffing](https://reactjs.org/docs/reconciliation.html)algorithm:

1. Comparing the types
2. Comparing the attributes(props)
3. Comparing the children

And of course there are tons of optimization under the hood, that makes React so powerful and beautiful UI library.

> If you liked this and [previous](https://dev.to/aibolik/create-your-own-virtual-dom-to-understand-it-part-1-3g4e) posts feel free to like(❤) and "unicorn" it, that will motivate me to do stuff like this more. Thanks for reading!


> _UPDATE 24.11.2019: If you want to learn React by doing many exercises, feel free to sign up to my upcoming course [30-day-React](https://aibolik.github.io/30-day-react/)_.

Resources:

- [Stefan Judis: What the v…DOM? | Web Rebels 2018](https://youtu.be/kghSjWmNJyQ)
- [Implementation of this experiment by Stefan Judis in CodePen](https://codepen.io/stefanjudis/pen/vjYWNO)
- [GitHub repo of this experiment](https://github.com/aibolik/simple-vdom)
- [React’s diffing algorithm](https://reactjs.org/docs/reconciliation.html)