June 28, 2016

State of the Virtual DOM

By Jscrambler | 4 min read

virtual_dom

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 a number of 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 in a similar fashion.

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

After installing the library with:

npm i virtual - dom

our Example.js should look like:

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
        })

Try Jscrambler For Free

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 DOM tree inside of a given HTML element. Should the method run more than once within the same root element, it will diff the new tree versus 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 don’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 own implementation of the virtual DOM . React’s API that 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 is able to manipulate it’s 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. 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.

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

Author
JscramblerThe 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 Posts

Subscribe to our weekly newsletter

Learn more about new security threats and technologies.

I agree to receive these emails and accept the Privacy Policy.