Javascript

State of the Virtual DOM

June 28th, 2016 | By Jscrambler | 4 min read

Virtual DOM or Virtual Document Object Model is a convention for changing the document tree structure of a page, including the style and content.

Conceptual implementations of a virtual DOM can be found in several modern frameworks that exist today. You might even be using some right now and you don’t even know it.

The most common examples of Virtual DOM would be React, Mithril, and jQuery. The key here is that they all use a unique method for rendering changes to the DOM. The original DOM, as specified by the WC3, was never really intended or optimized for creating dynamic user interfaces.

Along with having to use memory to rewrite the entire DOM tree, you also load properties/attributes that are processed by your browser on demand. Yes, it’s inefficient. Luckily the world is a better place thanks to the arrival of the Virtual DOM.

Virtual DOM

The central benefit of a Virtual DOM is that it’s fast, faster than any kind of manual DOM rendering or manipulation.

Think of your DOM as a tree with each node of content as a branch. If you want to grow a new tree and a set of branches every time you pick a fruit (changed content), it just wouldn’t be sustainable.

Instead of re-rendering the entire DOM tree, we can simply keep an eye on the changes we’ve made, only replacing those elements on our page with the use of diffing. This avoids resources re-rendering nodes on a page or performing taxing DOM interactions unnecessarily.

Essentially we’ve abstracted our slowpoke DOM and created a replica of it that only renders the DOM changes which is traversed much more easily. Most Virtual DOM implementations work similarly.

Here’s a simple example that implements a Virtual DOM using Matt Esch’s handy library.

After installing the library with:

npm i virtual - dom


Our Example.js should look like this:

var createElement = require('virtual - dom / create - element')
var h = require('virtual - dom / h')
var diff = require('virtual-dom/diff')
        var patch = require('virtual-dom/patch')
            /* we load Hypersrcipt along with our diffing and 
               patching modules available in virtual-dom*/
        var vel = h('h1', 'Welcome to the world of Virtual DOM')
        var el = createElement(vel)
        document.body.appendChild(el)

        //we then patch new virtual elements after diffing the old ones.
        setTimeout(function() {
            var newVirtualElement = h('h1', 'New Virtual World')
            var patches = diff(vel, newVirtualElement) //we
            patch(el, patches)
            vel = newVirtualElement
        })


We can simulate a synchronous event by creating a new virtual element in our setTimeout function. We then designate a new patch by comparing our old elements with our new ones.

Lastly, we patch those changes to the DOM. A trivial example but it’s an indicator of the benefits in much larger applications.

Mithril Virtual DOM

There’s also Mithril.js. A framework with a tiny footprint at only 7.8k and no dependencies has an even simpler virtual DOM API than React.

Mithril provides methods for generating a DOM tree inside of a given HTML element. Should the method run more than once within the same root element, it will differentiate the new tree from the old one and intelligently modify only portions that have changed.

Compared to React, this optimized diffing algorithm doesn’t affect properties within elements of the DOM like inputs and focus ensuring safe user interactions. Here’s an example of Mithril Implementing Virtual DOM:

Example.js:

ensuring safe user interactions. Here’s an example of Mithril Implementing Virtual DOM:

Example.js:

var elements = [];

function Element() {
    this.isNew = true;
}

function elementView(element) {
    return m('li.element', {
        className: thing.isNew ? 'new' : 'notNew',
        config: function() {
            thing.isNew = false;
        }
    });
}

m.module(document.body, {
    controller: function() {},
    view: function() {
        return [
            m('button', {
                onclick: function() {
                    elements.push(new Element)
                }
            }, 'Add a thing'),
            m('ul', elements.map(elementView))
        ];
    }
});


In our CSS we denote the new elements rendered in red and untouched elements in black

CSS:

.element { & : before {
        content: ‘Element’
    }

    & .new {
        color: red;
    }
}


Notice how the state of our old elements doesn’t change as new ones are created. Mithril is great because you enjoy the same benefits in performance, security, and productivity with just plain old JavaScript functions.

React Virtual DOM

Facebook’s React.js provides its implementation of the virtual DOM.

React’s API allows users to describe a DOM tree directly in JavaScript. It does so by drawing a tree of custom objects representing a portion of the real DOM.

When a new div element is created it will create a React.div element, along with any children nodes like say an ordered list as React.ol. React can manipulate its virtual DOM quickly without needing the DOM to repaint thanks to its tree-diffing algorithm.

This stateless approach separates the view layer from the DOM, not only reducing complexity but improving performance as well. With React you are simply declaring how the view layer should look while abstracting the low-level DOM API methods.

Elements are rendered as if they were real DOM components. React controls the UI view by way of it’s components which in turn update the virtual dom. Those components specific to your app house the application-specific APIs and internal logic necessary for state management.

No matter the implementation, using Virtual DOM is about avoiding costly changes to the DOM. Those changes can be a detriment to performance if we call too many repaints of our application, especially at scale.

Conclusion

Whether you opt for Mithril’s minimal approach or React’s unique tree-diffing, the benefits are evident when you enjoy the optimized performance of a Virtual DOM on mobile devices.

If you want to secure your JavaScript source code against theft and reverse engineering, start your Jscrambler free trial.

Jscrambler

The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Javascript

How to manipulate DOM using a service worker

Service workers are JavaScript workers that run in the background of a page, act as a proxy between the browser and the server, and manipulate the DOM.

February 14, 2023 | By Jscrambler | 4 min read

Web Development

Optimizing React Rendering through Virtualization

Even though React is fairly performant out-of-the-box, sometimes you need to tune it. Learn how to implement a context specific optimization.

October 4, 2016 | By Juho Vepsäläinen | 5 min read

Section Divider