What is virtual DOM?
In short, virtual DOM is a key part of an emerging trend in building speedy, sane web UIs
But let's dig deeper. I started hearing mention of this mystical new type of DOM earlier this year. Eventually my curiosity got the best of me and I searched "what is virtual dom?" This was one of those cases where a quick search wasn't helping me grasp the idea, but it did reveal that a trend existed.
Then a few weeks ago I came across a closed StackOverflow question that asks “What is virtual DOM?” There doesn’t seem to be a comprehensive answer to this question anywhere, and I feel like this trend could be a Big Deal™, so I’m writing my first blog post in years.
To clear up some confusion off the bat, consider this disambiguation:
- Shadow DOM — A W3C working draft standard. Shadow DOM is not directly related to any virtual DOM discussion at this point. Shadow DOM is an aspect of web components that enables style encapsulation which you can read more about elsewhere.
- Virtual DOM — Not a standard. Virtual DOM solutions are built on top of standard DOM. They still utilize DOM eventually — they just do it as little as possible and very efficiently.
Background on standard DOM
In order to understand a virtual version of some thing, you must first understand the original thing. I originally included a refresher on the DOM within this post, but it got a bit long, so I’ve broken it out to What is the DOM?. If you want to brush up on the basics head there first.
I mention in What is the DOM? that it is an abstraction of a document with some pros and cons. To help make it clear why there is even a need for virtual DOM, let’s look at some of the good and the bad that standard DOM brings to the table.
The DOM is good for...
- Cross-platform, cross-browser (pretty much) scripting.
- See quirksmode.org's DOM compatibility tables. They are mostly green these days which is fantastic.
- A solid base for progressive enhancement.
- Simple content pages
The DOM is bad for...
- Complex web apps. Many current web development trends make it too easy to execute slow performing DOM manipulations.
- Developing new specifications. The complexity of the DOM leads to stagnation, new specifications that build on DOM can fail.
- Backwards compatibility is really hard.
The DOM was never optimized for creating dynamic User Interfaces on the web
jQuery’s DOM manipulation methods were a godsend and helped ease the pain of working with DOM idiosyncrasies, but they did little to solve the performance problems underlying it. As we continue to shift toward mobile as our primary mode of web browsing, slow UI interactions are still common and tend to show up more pronounced than ever.
We’re still trending towards single page web apps (SPA) in many cases, and outright bloated pages of third-party content. We’re often slow after first render. We’re manipulating 1000’s of DOM elements per “page” and asynchronously loading HTML kitchen sinks into our “pages” and applying all sorts of styles to them on the fly. These aren’t simple HTML documents anymore and a lot of the slowdown now happens throughout the user experience. After all assets have downloaded, we’re typically just moving DOM elements around and updating their contents, so why so slow? A big part of this problem is slow DOM manipulation functions in popular libraries.
The number of DOM elements on a page at a given time can be HUGE
- twitter.com has 30k+ nodes after a few minutes of scrolling.
- facebook.com has 17k+ nodes after a few minutes of scrolling.
Web apps in 2014 are still not feeling as fast as many wish they would.
As far back as 2008 the web developer community began formulating some loose best practices to get around inefficient DOM manipulation. More recently companies have codified these in their own ways.
However, even following these best practices, there’s still a lot of complexity and pain when web developers go to create their next UI with any given application framework. AngularJS for example, a fantastic framework for creating web apps, still suffers from slow DOM operations that need Angular-specific workarounds.
A new approach
Best practices haven’t cut it for a lot of teams building complex UIs. There is still a lot of debate going on over how to best use the DOM and how to structure reusable componenents. One emerging trend centers on abstracting DOM manipulation even further than in the past. I am calling these libraries and frameworks virtual DOM projects.
What these libraries and their creators realized, is that in order to build faster and more maintainable UI’s for the web, they had to lock down how developers interact with the DOM. Instead of complex best practices around updating and controlling a multitude of interrelated, nested objects, virtual DOM libraries now re-render large chunks of the UI all the time as a rule. They aim to achieve a faster and more maintainable UI by allowing only the most speedy of DOM manipulations to occur, and only at the behest of the library itself.
This emerging approach of a virtual DOM goes beyond batching DOM manipulations. It goes beyond HTML templating for the most part too. These libraries tend to handle chunks of UI via declarative object abstractions. These abstractions are often called components.
By diffing the before and after chunks of custom, framework-defined component objects, and only writing changes to DOM when absolutely necessary, the virtual DOM approach has proven to be a viable method for increasing not only performance, but maintainability as well.
There are a handful of new libraries and frameworks with virtual DOM ideas at the core of their code. Many existing library developers and the web developers that utilize them are also curious about virtual DOM and how they can take advantage of the approach in their current projects or within their current framework of choice. Famo.us is a widely-hyped framework that also sidesteps the DOM as much as possible.
- Elm — “Blazing Fast HTML”
- Mercury — “A truly modular frontend framework”
- Om — “ClojureScript interface to Facebook's React”
- Ractive — “The diamond age of web development”
- TagTree — “A React-like UI framework in Dart”
- WebSharper.UI.Next — “A new generation of reactive web applications.”
- virtual-dom — “A Virtual DOM and diffing algorithm”
Hit me up if you know of any others!
In the wild examples of virtual DOM:
- TextArea hooked to app state. James Long’s excellent article is full of mini-demos like this one.
- React + D3
- D3 in a virtual DOM with domino.js
- AngularJS + React
- Pedestal + Om
- React + bacon.js