Q23: Build a Basic Virtual DOM Tree Diffing Engine
Build a diffing engine that compares old and new Virtual DOM node trees recursively, generating patch descriptions for updates, replacements, and removals.
VNode Diffing Algorithm
function diff(oldVNode, newVNode) {
if (newVNode === undefined) {
return { type: 'REMOVE' };
}
if (typeof oldVNode === 'string' || typeof newVNode === 'string') {
if (oldVNode !== newVNode) return { type: 'TEXT', text: newVNode };
return null;
}
if (oldVNode.type !== newVNode.type) {
return { type: 'REPLACE', newVNode };
}
const propsDiff = diffProps(oldVNode.props || {}, newVNode.props || {});
const childrenDiff = diffChildren(oldVNode.children || [], newVNode.children || []);
return {
type: 'UPDATE',
props: propsDiff,
children: childrenDiff
};
}
function diffProps(oldProps, newProps) {
const patches = [];
for (let key in newProps) {
if (newProps[key] !== oldProps[key]) patches.push({ key, value: newProps[key] });
}
for (let key in oldProps) {
if (!(key in newProps)) patches.push({ key, value: undefined });
}
return patches;
}
function diffChildren(oldChildren, newChildren) {
const max = Math.max(oldChildren.length, newChildren.length);
const childPatches = [];
for (let i = 0; i < max; i++) {
childPatches.push(diff(oldChildren[i], newChildren[i]));
}
return childPatches;
}💡 Compares VNodes recursively, returning REPLACE patches when tag types change or UPDATE patches for modified props/children.
Key Takeaways
- Compares VNodes recursively to calculate minimal structural edits.
- Replaces entire subtrees when VNode type tags differ.
Knowledge Check
What patch action is returned when comparing two VNodes with different element type tags (e.g. div vs section)?