25
Why Virtual DOM?
Plug: I help develop
million
: <1kb virtual DOM - it's fast!
The Virtual DOM was initially pioneered by the React authors on the basis of making delarative JavaScript patterns performant - but how? To understand this, we need to quickly review how traditional DOM manipulation works.
Generally speaking, the easiest way of changing the DOM ("Modifying the HTML") is to mutate the innerHTML
property on an element. For example, if I want to add a div
element in the document body, I could do something like this:
document.body.innerHTML = '<div>Hello World!</div>';
// <body> now has a <div>Hello World!</div> child.
This seems to be computationally performant, but it really isn't. While the action of reassignment is computationally performant, the DOM repaint ("Updating what the user sees") is not. This is because innerHTML
needs to parse DOM nodes from a string, preprocess, and append it, resulting in less-than-optimal performance. The issues with performance are increasingly noticable when there are more children/attributes and when the interval of mutation is shorter.
So, how is this issue fixed? Well, instead, we do pinpoint changes to the DOM. For example, this solution would be almost 10x faster than the innerHTML
solution.
const div = document.createElement('div');
div.textContent = 'Hello World!';
document.body.appendChild(div);
While this is simple enough, once you start performing continous mutations, more complexity arises. This is why the virtual DOM was created - to allow you to write declarative content (like the string in the innerHTML
example) while harnessing performance by making only pinpoint changes to the DOM.
The virtual DOM is a tree of virtual nodes that represents what the DOM looks like. virtual nodes are light, stateless, and are JavaScript objects that only contain necessary fields. virtual nodes can be assembled into trees, and "diffed" to make pinpoint changes to the DOM.
While this is efficient, it has some caveats. Notably, diffing is not computationally free. Traversing the trees have O(n^3)
time complexity, meaning the more children, the longer the time it will take to perform the action. To solve this, Million was created.
Million provides five major improvements: granular patching, fewer iterative passes, fast text interpolation, keyed virtual nodes, compiler flags.
- Granular patching: Instead of just replacing the entire element when there is a difference in props or children, only the necessary props are changed.
- Fewer iterative passes: Million attempts to reduce the amount of passes during diffing, allowing for better time and space complexity.
-
Fast text interpolation: Instead of replacing text nodes with DOM methods, Million uses compiler flags to set the
textContent
of elements to boost performance. - Keyed virtual elements: This allows for the patching algorithm to skip nodes if the new virtual element key is the same as the old one, minimizing the amount of unnecessary work.
- Compiler Flags: This allows for the patching algorithm to skip condition branches, meaning less work is done.
Thanks for reading! Drop a star to Million or follow/react to this article for more Virtual DOM content!
25