Building a Simple Virtual DOM Diff Algorithm: From Concept to Code
This article explains the Virtual DOM concept, outlines a state‑driven rendering approach, implements a minimal Virtual DOM (VD) structure, creates a diff algorithm to generate patch objects, applies those patches to the real DOM, and compares its performance with full re‑rendering.
Introduction
The two most popular front‑end frameworks, React and Vue, both rely on Virtual DOM (VD) to improve rendering efficiency. This article shows how VD works and builds a pure, framework‑agnostic implementation of a simple VD and a diff algorithm.
Design Idea
In a VD‑based framework the UI is a direct mapping of the application state: UI = render(state). When the state changes, a new VD tree is generated, compared with the previous one, and a patch object describing the differences is produced. The patch is then applied to the real DOM.
Patch Object Structure
Four node operations are defined (create, remove, replace, update) and two property operations (remove, update):
const nodePatchTypes = {
CREATE: 'create node',
REMOVE: 'remove node',
REPLACE: 'replace node',
UPDATE: 'update node'
};
const propPatchTypes = {
REMOVE: 'remove prop',
UPDATE: 'update prop'
};Implementation
A timer increments state.num every 500 ms. The render function creates the initial VD, converts it to a real DOM element with createElement, and appends it to the container. On each tick a new VD is generated via view(), diff(preVDom, newVDom) produces a patch object, and patch(element, patchObj) updates the DOM.
let state = { num: 5 };
let timer;
let preVDom;
function render(element) {
const vdom = view();
preVDom = vdom;
const dom = createElement(vdom);
element.appendChild(dom);
timer = setInterval(() => {
state.num += 1;
tick(element);
}, 500);
}
function tick(element) {
if (state.num > 20) { clearTimeout(timer); return; }
const newVDom = view();
const patchObj = diff(preVDom, newVDom);
preVDom = newVDom;
patch(element, patchObj);
}
function diff(oldVDom, newVDom) { /* ...node, props, children diff logic... */ }
function patch(parent, patchObj, index = 0) { /* ...apply CREATE, REMOVE, REPLACE, UPDATE... */ }
function patchProps(element, props) { /* ...apply prop patches... */ }Performance Comparison
The demo shows that with a very small DOM tree the time spent on constructing the render tree and painting is minimal, while the JavaScript diff calculation adds overhead. In this simple case a full re‑render actually takes less total time, illustrating that VD benefits become noticeable only in larger, more complex applications.
Images illustrate the update process and the performance comparison:
Conclusion
The article demonstrates a complete workflow: generate a VD tree, diff it against the previous version, create a patch object, and apply the patch to the real DOM. It also provides a brief performance analysis and hints at future optimizations to be covered in the next installment.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Youzan Coder
Official Youzan tech channel, delivering technical insights and occasional daily updates from the Youzan tech team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
