Frontend Development 11 min read

Understanding Vue's Diff Algorithm: A Step‑by‑Step Guide

This article explains Vue's diff algorithm in detail, covering prerequisite concepts about VNode, left‑ and right‑side comparisons, handling arrays of different lengths, and the complete implementation with code examples to help developers grasp how Vue efficiently updates the DOM.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Vue's Diff Algorithm: A Step‑by‑Step Guide

This article introduces the Vue diff algorithm, a core part of Vue's virtual DOM rendering process, and demonstrates how to compare two arrays of VNode objects to efficiently update the real DOM.

Prerequisite Knowledge

Understand that Vue 3 uses vnode objects.

Know that a vnode is essentially a JavaScript object.

Be aware that a vnode has a children property which can be a string or an array.

With this background, you can start analyzing how Vue implements diff by comparing two arrays.

What to Do

Assume you have two arrays and need to find their differences. Consider three scenarios:

Same elements at the left side, differences later (image omitted).

Same elements at the right side, differences earlier (image omitted).

One array is longer than the other.

Left‑Side Comparison

Initialize i = 0 and increment it until a mismatching node is found, using the condition i <= c1.length - 1 && i <= c2.length - 1 and checking c1[i] === c2[i] . The index i then marks the first differing position from the left.

Right‑Side Comparison

The right‑side comparison mirrors the left‑side logic but iterates from the end of the arrays toward the start, using separate indices for each array.

Combining Left and Right

For example, comparing [A,B,C,D,E,F] with [A,B,D,C,E,F] yields a left‑side index of 2 and a right‑side index of 3.

function diff(c1: VNode[], c2: VNode[]) {
  let e1 = c1.length - 1;
  let e2 = c2.length - 1;
  let i = 0;
  // left
  while (i <= e1 && i <= e2) {
    let n1 = c1[i];
    let n2 = c2[i];
    if (isSomeVNodeType(n1, n2)) {
      // unchanged element, render directly
    } else {
      break;
    }
    i++;
  }
  // right
  while (i <= e1 && i <= e2) {
    let n1 = c1[e1];
    let n2 = c2[e2];
    if (isSomeVNodeType(n1, n2)) {
      // unchanged element, render directly
    } else {
      break;
    }
    e1--;
    e2--;
  }
}

function isSomeVNodeType(n1: VNode, n2: VNode) {
  return n1.type === n2.type && n1.key === n2.key;
}

When the New Array Is Longer

If the new array is longer, the differing region lies between i and e2 . The algorithm inserts the extra nodes:

if (i > e1 && i <= e2) {
  while (i <= e2) {
    // insert c2[i]
    i++;
  }
}

When the Old Array Is Longer

If the old array is longer, the algorithm removes the surplus nodes:

if (i <= e1 && i > e2) {
  while (i <= e1) {
    // delete c1[i]
    i++;
  }
}

Handling Equal Length with Internal Differences

When lengths match but a middle segment differs, the algorithm creates a mapping of new nodes, deletes nodes absent in the new array, and moves nodes that changed position. It uses a Map for key‑to‑index lookup and computes the longest increasing subsequence to minimize moves.

// Build key‑to‑new‑index map
const keyToNewIndexMap = new Map();
for (let i = s2; i <= e2; i++) {
  const newChild = c2[i];
  keyToNewIndexMap.set(newChild.key, i);
}

// Track old‑to‑new index mapping
const newIndexToOldIndexMap = new Array(toBePatched);
for (let i = 0; i < toBePatched; i++) {
  newIndexToOldIndexMap[i] = 0;
}

// Process each old node
for (let i = s1; i <= e1; i++) {
  const preChild = c1[i];
  // ... (logic to find newIndex, delete, or mark for move)
}

Summary

Bidirectional comparison isolates the differing region between two VNode arrays.

Key comparison determines whether two VNodes represent the same element.

Within the differing region, only three operations are needed: insert, delete, or move.

A Map is used to build a lookup table for fast key‑based matching.

The longest increasing subsequence helps identify nodes that can stay in place, reducing the number of moves.

If the article helped you, feel free to follow, like, and bookmark.

JavaScriptVuediff algorithmcodeVNode
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.