Baseline 不是為了證明 Vue 3.5 好或不好,只是先留下「升級以前的樣子」
昨天,我們讓 Reactive Chain Generator 可以自由調整 Dependency Depth,藉由不同的深度觀察 Dependency Chain 變深之後,Vue Runtime 究竟多做了什麼?
不過在真的開始比較之前,我覺得要先搞清楚 Vue 3.5 在這個案例裡,平常到底是怎麼跑的?
因為如果連「正常狀態」長什麼樣子都不知道,明天拿 Vue 3.6 來比較時,即使數字變了,我們也很難知道,到底是哪一個環節發生了變化?
這次的範例沒有大量 DOM,也不是在測試「一次 Render 幾千個節點」,只是很單純的 source.value++ → Reactive Update → Vue Runtime 開始處理這次變化,所以今天真正想回答的,其實只有三個很直覺的問題:

Update Duration當我們執行:
source.value++
Vue 從「資料發生變化」到「這一輪更新完成」,到底花了多少時間?這就是 Update Duration。
可以把它想成當我按下按鈕之後,Vue 處理完這次更新到底花了幾毫秒?
這次實驗裡,我用:
source.value++
await nextTick()
把這一輪更新當成一次完整的測量範圍,整個概念可以先簡化成:
source.value++
↓
Vue Reactive System
│
├── Computed
├── Watcher
├── Scheduler
└── Component Update
↓
nextTick()
注意:這是一個簡化示意圖,不代表每次更新都一定會經過所有步驟。
除了想知道 Render 到底多快以外,同時也是在找尋 Vue 處理這次 Reactive Update,總共花了多少時間?
因為後面如果發現 Depth ↑ && Update Duration ↑,直接下「一定是 Render 變慢」的結論,就很敷衍,還需要繼續往下看層層架構的原因。

直覺上都會認為 computed 越多,Reactive Chain 越深,所以 Vue 做越多事情 Render 應該也越多,但是實際上這幾件事情不是同一件事。
如果 DEPTH 從 5 增加到 100,Render Count 仍然維持不變
| Depth | 5 | 50 | 100 |
|---|---|---|---|
| Render Count | 1 | 1 | 1 |
那就出現了一個很重要的線索:
Dependency Complexity ↑
│
├── Runtime Work ↑
│
└── Component Render ──→ 不一定增加
這代表我們不能只看到「Update 變慢」,就直接甩鍋給 Rendering,這裡 Runtime Cost 和 Rendering Cost 必須拆開看。
其實是前兩個指標沒有辦法直接回答這個問題!因為只能知道 Update Duration 省下成本,但是不知道成本到底去哪了?
是:
這時候單看我們自己的 Runtime Metrics 還不夠,所以第三個觀察會交給 Chrome DevTools,打開 Performance 依照以下流程開始錄製:
Record
↓
Trigger Update
↓
Stop
接著觀察 JavaScript Execution Time、Main Thread Activity 以及 Flame Chart,這次 Update 的 CPU 時間主要花在哪裡?

接著我把同一次 Update 丟進 Chrome DevTools Performance,原本期待看到的是:
Reactive Effect
Computed
Watcher
Scheduler
Render
但第一次錄製時,看到的卻比較像:

Synthetic Script
pointerover
Animation Callback
...
一開始會覺得 Vue Runtime 怎麼不見了?難道沒有運作?但是我可以看到畫面呀!
後來把深度加到最大,才發現其實不是 Vue 沒有工作,而是工作量太小,Vue 更新時間短到 Chrome 幾乎無法完整展開 Runtime Call Stack。
| DEPTH | Update Duration |
|---|---|
| 5 | 1.7 ms |
| 20 | 2.6 ms |
| 100 | 20.1 ms |

當一次 Vue Update 只有非常短的 CPU 工作量時,瀏覽器的 Performance Trace 不一定能把我們真正想看的 Runtime Call Stack 清楚展開。
換句話說,剛開始看到的,比較像是 Browser 在做什麼;還不夠像 Vue Runtime 在做什麼。
前面遇到的問題,其實到這裡,其實已經可以看到一些現象:
DEPTH ↑
│
├─ Update Duration ↑
│
├─ Render Count ≈ 穩定
│
└─ CPU Work ↑
所以要結案了嗎?嗯...應該說故事剛開始,今天看到的東西,可以先整理成:
Observation
│
┌───────────┼───────────┐
▼ ▼ ▼
Duration ↑ Render ≈ 1 CPU ↑
│ │ │
└───────────┼───────────┘
▼
還不能下結論
│
▼
Vue 3.6 是否真的改善?
所有疑問在今天都不會有結果,說真的,畢竟今天做完 baseline 還不知道:
這些問題,留給後面的 Validation。
所以今天最重要的成果,不是某一個 ms 數字,之後更換任何一個版本都會讓我們更加清楚:
Vue 3.5
│
▼
Current Behavior
│
┌────────────┼────────────┐
▼ ▼ ▼
Duration Render Count CPU
│ │ │
└────────────┼────────────┘
▼
Baseline
│
┌─────────┴─────────┐
▼ ▼
Vue 3.6 Traditional Vapor
這樣我們最後看到的「改善」,才有機會回答真正重要的問題:
到底變好了,還是只是看起來不一樣?