Virtual DOM DiffLoading saved progress…

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.
WE’RE LISTENING

Help make UIReady better

Found a bug or have an idea? Tell us about it.

Up to 3 files · 5 MiB each · JPG, PNG, WebP, MP4, WebM, MP3, M4A or WAV