Reverse Virtual-DOM
--
Let’s explore a concept that can be introduced into React and other Virtual-DOM implementations. I just want to point out that this is not about new virtual-dom diffing logic, it’s just a feature for use with existing virtual-DOMs.
Reverse Virtual DOM
In theory this is what we do in React:
Virtual DOM
- Structure HTML in app.js
- Modify the virtual-nodes
- Rewrite to the DOM
But how about…
Reverse Virtual DOM
- Structure HTML in app.html
- Grab the HTML and convert to virtual-nodes
- Modify the virtual nodes
- Rewrite to the DOM
So let’s look at the benefits:
- SEO (No server side rendering required)
- Cleaner Semantic for non-JS developers
- In JS you only create and modify what will change
- Reduced TTFB
- A more coherent team workflow
In regards to the last point, typically a developer responsible for styling would create at least the basics of the HTML and CSS before the JS developer creates the interactivity. But if the styling developer is delayed and the HTML is not yet ready the JS dev can still work and view the interactive components as usual.
The nice thing here is the efficiency and improved end results. This is not remotely the same as building a standard React app over HTML, that’s double the work in most cases. If you think this can be done by targeting specific elements into React, without rendering the entire page you will likely lose some of the performance advantages of React.
I created a demo of this concept last year using virtual-dom, I wouldn’t be surprised if a reverse-virtual-dom-like library is lingering about somewhere with zero stars, it’s just one of those things where the concept is so tiny the value is completely overlooked.
Reverse Virtual DOM Interface
Below is usage of a crappy example I made last year using virtual-dom. I built createVirtualNodes() which converts a DOM tree into a virtual-node, and createNodes() which converts a virtual-node tree into DOM nodes. So it’s pretty much a demo copying from the HTML and rewriting without any diffing.
The above is not a practical interface. Here’s what we really need to do:
- Get the root element and convert it into a virtual-node-tree
- Search for a specific virtual-node within that virtual-node-tree in the style of querySelector: (‘#some-selector’) | (‘.someSelctor’) |..All(‘.someSelctor’)
- Create the interactive HTML template using h, JSX, or whatever.
- Replace that specific part over the original part of the virtual-node-tree
- Diff -> patch -> Render
I know you want to but please don’t complicate things. The concept is very simple, you can build it for your favourite virtual-DOM implementation React / Vue / Angular2/ SnabbDOM + etc all you need to do is:
- Create a simple createVirtualNodes like API which converts a DOM tree into your virtual-node implementation.
- Create a virtualNodeQuerySelector like API that returns a specific part of the virtual-node-tree.
- Create a replaceVirtualNodeChild like API that allows a modified/ new virtual-node part to replace a virtual-child-node of a virtual-node-tree.
I do plan to implement this concept in snabbdom or <insert-hot-new-virtual-dom-here> at some point in the future since virtual-dom is pretty much discontinued. But please feel free to beat me to it.
I don’t think this is about competing with the standard way of using a virtual-dom implementation. They are both tools that can go hand in hand.
There’s also FastDOM which is not a virtual-DOM but a light-weight way to read and mutate the DOM efficiently, sometimes it can be more performant than using a VDOM.
Although we’ve moved beyond jQuery I don’t believe in the one interface fits all eco systems in JavaScript. You could paint everything with the same paintbrush but you would probably get better results with a variation or sometimes you just need a tiny scraper.
Thanks for the read ;-)