Does Vue’s Vapor Mode Really Eliminate Diff? A Deep Dive into the Source
This article investigates Vue 3.6’s new Vapor mode, comparing its compilation output with traditional Vue, revealing that while most bindings skip the virtual‑DOM and diff steps, the v‑for directive still relies on a full diff algorithm for complex list updates.
Introduction
Hello, I’m Naiderli. While exploring Vue 3.6 new features, I discovered two mysterious packages in the Vue codebase: runtime‑vapor and compiler‑vapor, which sparked my curiosity about Vue’s internal implementation.
Starting with a Simple Example
Traditional Vue compiles a simple template into a render function that creates a virtual DOM node and then performs a diff when name changes:
<template>
<div>{{ name }}</div>
</template> function render() {
return h('div', null, ctx.name) // create virtual DOM
}When name updates, Vue must:
Create a new virtual DOM
Diff it against the old virtual DOM
Apply the differences to the real DOM
Vapor’s “Magic”
The Vapor compiler produces code that creates the real DOM directly and updates it with setText, completely bypassing virtual DOM creation and diffing:
function _render() {
const t0 = template(`<div></div>`)
const n0 = child(t0, 0)
renderEffect(() => {
setText(n0, ctx.name) // update DOM directly
})
return t0
}Diff Still Exists!
In packages/runtime‑vapor/src/apiCreateFor.ts a diff algorithm similar to Vue 3.5’s patchKeyedChildren is present, especially for the v‑for case:
const renderList = () => {
if (getKey) {
// traditional diff algorithm
let i = 0
let e1 = oldLength - 1
let e2 = newLength - 1
// 1. sync from start
while (i <= e1 && i <= e2) {
if (tryPatchIndex(source, i)) {
i++
} else {
break
}
}
// 2. sync from end
while (i <= e1 && i <= e2) {
if (tryPatchIndex(source, i)) {
e1--
e2--
} else {
break
}
}
// 3. longest increasing subsequence optimization
const increasingNewIndexSequence = moved
? getSequence(newIndexToOldIndexMap)
: []
}
}This code is almost identical to the classic patchKeyedChildren algorithm, confirming that diffing is retained for list rendering.
Why v‑for Opens a “Back Door”?
For simple bindings, the compiler can determine the update target at compile time and update the DOM directly, eliminating diff overhead. However, list rendering must handle insertions, deletions, moves, and updates, which requires a robust diff algorithm to maintain performance and UI consistency.
Scenario
Vapor Strategy
Reason
Simple binding {{ name }} Direct update, no diff
Update target known at compile time
Conditional rendering v‑if Simple replace, no diff
Only show/hide, no complex changes
List rendering v‑for Retain diff algorithm
Need to handle complex insert/delete/move
My Understanding
Vapor does not discard diffing entirely; it applies fine‑grained scenario discrimination:
In about 90% of common cases, updates are performed without diff.
In complex list scenarios, the mature diff algorithm is kept.
Comparison Summary
Update Scenario
Vue 3.5
Vapor Mode
Text binding
Virtual DOM + diff
Direct DOM update
Attribute binding
Virtual DOM + diff
Direct DOM update
Conditional rendering
Virtual DOM + diff
Simple replace
List rendering
Virtual DOM + diff
Diff retained
Conclusion
The answer to “Does Vue Vapor really have no diff algorithm?” is: Most of the time it skips diff, but for v‑for it still uses the full diff algorithm.
Final Thoughts
Don’t be fooled by sensational headlines – “completely dropping diff” is inaccurate.
Technical decisions involve trade‑offs – Vue’s choice reflects engineering pragmatism.
Source code is the best teacher – digging into the repo reveals the truth.
Maintain a rational attitude – new techniques are exciting but must be understood in context.
Vapor shows promising performance gains in most scenarios, though list rendering still relies on diff. I’ll continue to follow Vue 3.6 releases and share more practical insights.
Article based on analysis of Vue 3 minor branch source code. Related sources: https://github.com/vuejs/core/tree/minor/packages/runtime-vapor https://github.com/vuejs/core/tree/minor/packages/compiler-vapor
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.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.
