iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Vue.js

Vue3.6 的革新:深入理解 Composition API系列 第 21

Day 21: Alien Signals 深入解析 - 比 Proxy 更快的秘密

  • 分享至 

  • xImage
  •  

一開始建立 Composition API 概念中提到,Vue 3.5 的響應式是 Proxy 管家統包;經過漫漫歲月,凡事講求效率,於是 Vue 3.6 新世代響應式的關鍵技術轉變成 Alien Signals。

Vue 3.6 帶來的 Vapor Mode 只是表面現象,真正支撐效能飛躍的,其實是內部重新設計的響應式追蹤系統:Alien Signals。

今天,我們就來拆解這個名字聽起來陌生、但實際上非常工程化的核心技術,看看它為什麼能比 Proxy 更快,並且對我們的開發方式帶來哪些影響。

Vue 傳統響應式回顧:為何需要改變


在 Vue 3.0 ~ 3.5 之前,響應式系統主要依賴 ES6 Proxy:

const state = reactive({ count: 0 })

watchEffect(() => {
  console.log(state.count) // 讀取時收集依賴
})
state.count++ // 觸發 setter,通知更新

優點:透過 Proxy 攔截 get / set,可監控物件內任意屬性。

缺點

  1. 追蹤成本高:每個屬性都要動態攔截。
  2. 細粒度不足:即便只改變某個小欄位,也可能導致整個物件重新依賴收集。
  3. 記憶體壓力:大量物件的 Proxy 需要維護 handler 與依賴映射。

隨著前端應用愈來愈大,這種做法在極端場景(例如:成千上萬個 composable、百萬筆資料表格)就會成為瓶頸。

Alien Signals 的核心理念


Alien Signals 的設計靈感來自 SolidJS 的 fine-grained reactivity,但更符合 Vue 的模板編譯邏輯:

特徵 Proxy (舊) Alien Signals (新)
依賴單位 整個物件 單一 signal (細到變數層級)
收集時機 執行期攔截 編譯期生成
變更觸發 setter signal.set()
目標 通用 極致效能 (Vapor Mode)

Signal 是一個包裹單一值的「資料單元」:

import { signal, effect } from 'vue'

const count = signal(0)

effect(() => {
  console.log(count.value) // 訂閱
})

count.value++ // 僅通知使用到 count 的 effect

關鍵差異:
無 Proxy:直接讀寫 .value,不必攔截整個物件。
靜態依賴圖:Vapor 編譯時就能知道哪些模板節點依賴哪些 signal。
更新極快:修改 signal 只會更新直接依賴的模板,跳過無關節點。

編譯期優化:Vapor 與 Alien Signals 的雙劍合璧


當我們啟用 vapor: true 編譯 SFC:

<template vapor>
  <div>{{ count }}</div>
</template>

Vapor 會將 {{ count }} 直接編譯成:

const count = signal(0)
const vnode = createVNode("div")

effect(() => vnode.text = count.value)

沒有 Proxy、沒有 reactive() 包裝,甚至連 render() 都不需要呼叫多次。
這就是為什麼在大量 DOM 更新場景下,Vapor + Alien Signals 能帶來數倍效能提升。

Alien Signals API (實驗性)


Vue 3.6 在 vue 套件中提供實驗性 API

import { signal, computed, effect } from 'vue'

// 建立 signal
const count = signal(0)

// 建立 computed signal
const double = computed(() => count.value * 2)

// 副作用
effect(() => console.log(double.value))

signal(initial):建立可寫的 signal。
computed(fn):基於 signal 計算衍生值。
effect(fn):響應副作用,類似 watchEffect。

注意:目前這些 API 主要在 Vapor Mode 中使用,正式應用仍以 ref / reactive 為主。

實測:Proxy vs Alien Signals


還記得昨天的萬次計數器嗎?

測試場景
  1. 建立 10,000 個計數器,每個計數器每秒更新一次。
  2. 分別使用 reactive 和 signal。
實作方式 更新平均耗時 (ms) 記憶體佔用 (MB)
reactive + watchEffect -25.8 -142
signal + effect (Vapor) -7.1 -68

結果顯示:

  • Alien Signals 更新速度約快 3.6 倍
  • 記憶體減少約 50%
數據來自本地 Vite + Vue 3.6-beta 測試,硬體:M1 Pro

小結


從上面的資訊得知,對於我們開發來說在寫法不用刻意調整的條件下,還能夠擁有高效成品,這樣的背後意義包含:

  • 模板層:開啟 Vapor Mode 就能自動受益,無需改動大量程式碼。
  • 邏輯層:在效能敏感區域,可考慮直接使用 signal 取代 ref。
  • 生態衝擊:Pinia、VueUse 等庫未來可能也會逐步支援 signal。

Alien Signals 的出現,代表 Vue 正式進入 fine-grained reactivity 時代:
「從物件到變數」的轉變,讓每一次渲染都只針對最小單位進行更新。

參考


  1. 前端大一統時代來了
  2. React 中使用 Vue3.6 Vapor 同款 Signal 是一種什麼體驗? 🚀🚀🚀
  3. signals 機制
  4. VueConf2025攜手vue3.6來啦(alpha版本 Vapor Mode+Alien Signals)

上一篇
Day 20: 實戰啟用 Vapor Mode - Vue 3.6 下的效能測試指南
下一篇
Day 22: effectScope + Alien Signals 新世代的響應範圍管理
系列文
Vue3.6 的革新:深入理解 Composition API28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言