All questions

Virtual DOM Diff

Premium

Virtual DOM Diff

Rendering a vnode tree from scratch on every change would throw away the whole DOM each time — slow, and it loses focus, scroll, and selection. The virtual-DOM payoff comes from diffing: compare the new vnode tree against the old one and apply the minimum set of real-DOM changes. Same tag? Patch its props in place and recurse into children. Different tag or text? Replace just that node. This is React's reconciliation, in miniature.

Implement patch(parent, oldVNode, newVNode, index = 0) (with the given createElement/render). Mutate the DOM under parent so the child at index matches newVNode — updating props in place when the type is unchanged, replacing only when it truly changed, and recursing into children.

Signature

function patch(parent, oldVNode, newVNode, index = 0) {
  // mutates parent.childNodes[index] to match newVNode
}

Examples

const oldV = h('div', { id: 'a' }, 'hi');
container.appendChild(render(oldV));
const node = container.firstChild;

patch(container, oldV, h('div', { id: 'b' }, 'hi'));
container.firstChild === node; // true — SAME node, only id changed to 'b'

Notes

  • Four cases — no old → append; no new → remove; changed (different tag, or differing text) → replace; same element → update props + recurse children.
  • changed(a, b) — true if the types differ, two primitives differ (text change), or two elements have different type (tag).
  • Update props in place — remove props gone in the new vnode, set props that are new or changed (and swap event listeners).
  • Children by index — patch the overlapping children, append the extra new ones, remove the extra old ones (from the end). The win: unchanged nodes keep their identity.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium