iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
JavaScript

React 觀念架構:從js 基礎到Hook 底層邏輯 系列 第 14 篇

Day 14 Concurrent Mode 與 Fiber 架構:React 如何實現可中斷的渲染?

  • 分享至 

  • xImage
  •  

今天我們要進入 React 16+ 最具革命性的底層重建——Fiber 架構 與 Concurrent Mode(並行模式)。

這是解答「為什麼 React 即使在處理龐大 UI 更新時依然能維持滑順流暢?」

一、 舊版 Stack Reconciler 的痛點:不可中斷的同步渲染

在 React 15 及更早版本中,Reconciler(協調器)採用的是 Stack 演算法。它像是一條單行道,一旦觸發更新,就會透過遞迴同步呼叫所有組件:

[State 變更] ──► 同步遞迴走訪整個 VDOM 樹 ──► 渲染 DOM
                └─── (期間主執行緒完全被佔用,不可中斷) ───┘
  • 致命缺點:如果頁面的 VDOM 樹非常龐大,這段同步計算可能耗時 50ms~100ms 以上。

  • 掉幀現象:瀏覽器為了維持 60fps 的流暢度,每 16.6ms 就必須進行一次畫面重繪與輸入響應。一旦 JavaScript 佔用主執行緒超過 16.6ms,使用者的打字、點擊或動畫就會出現嚴重的卡頓 (Jank)。

二、 救世主誕生:React Fiber 到底是什麼?

為了打破這個限制,React 團隊歷時數年重新撰寫了核心演算法,推出 Fiber 架構。

Fiber 的雙重身份

  • 一種資料結構:取代了原本的 VDOM 節點。每個 Fiber 節點都是一個 JavaScript 物件,除了包含組件資訊外,還增加了 child(第一個子節點)、sibling(右側兄弟節點)、return(父節點) 等鏈表 (Linked List) 指標。

  • 一個執行單元 (Unit of Work):將原本龐大的「一整棵樹的遞迴比對」,拆解成無數個「微小的 Fiber 節點比對」。

     [Parent]
      /     ▲
   child  return
    /       \
[ChildA] ──sibling──► [ChildB]

因為改採用單向鏈表結構,React 不再需要依賴 JS 函數 call stack 的遞迴,而是可以用 while 迴圈隨時暫停、記錄進度,並在未來恢復執行

三、 Concurrent Mode(並行模式):時間切片與優先級調度

有了 Fiber 鏈表結構後,React 18 終於能夠完美支援 Concurrent Mode(並行模式)。

Concurrent Mode 的核心在於「時間切片 (Time Slicing)」與「優先級調度 (Priority Scheduling)」:

  1. 時間切片 (Time Slicing):React 將渲染任務切分成數個 5ms 左右的小分片。每執行完一個 Fiber 節點的比對,就會檢查瀏覽器是否有高優先級任務(如使用者點擊、鍵盤輸入)。

  2. 可中斷與恢復 (Interruptible Render):如果有高優先級任務,React 會立即暫停當前的背景渲染,將主執行緒交還給瀏覽器處理 UI 響應;待主執行緒空閒時,再繼續執行未完成的 Fiber 任務。

[Fiber Task 1] ──► [Fiber Task 2] ──► 🛑 收到使用者點擊事件!
                                         │ (暫停 React 渲染,先處理 UI 響應)
                                         ▼
[完成點擊響應] ◄─────────────────────────┘
      │
      ▼
[恢復執行 Fiber Task 3] ──► [Commit 到 Real DOM]

四、 雙緩衝機制 (Double Buffering)

為了確保在「渲染可暫停、可放棄」的情況下,使用者不會看到只渲染了一半的半成品畫面,Fiber 採用了顯示卡常見的 雙緩衝技術 (Double Buffering):

  • current 樹:代表目前在屏幕上渲染的 Real DOM 對應樹。

  • workInProgress (wip) 樹:在背景記憶體中正在進行 Diffing 計算與構建的新樹。

所有的可中斷計算都在 workInProgress 樹上進行。只有當背景樹完全比對完畢,準備進入 Commit 階段時,React 才會在一瞬間將指標切換過去(current = workInProgress),一次性更新至 Real DOM!


上一篇
Day 13 Render 瀑布流與效能坑:為什麼 Parent Render 會引發 Child 渲染?
系列文
React 觀念架構:從js 基礎到Hook 底層邏輯 共 14 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言