深入理解React Fiber機制
React Fiber 是 React 16 引入的核心協(xié)調(diào)算法重構(gòu),它解決了舊版 Stack Reconciler 的不可中斷、同步遞歸導(dǎo)致的卡頓問題。
簡單來說:Fiber 讓 React 的渲染過程從「一口氣干完」變成了「可中斷、可分片、可優(yōu)先級排序」的任務(wù)調(diào)度。
下面從三個關(guān)鍵維度展開:
一、為什么需要 Fiber?(痛點分析)
舊版 React(<16)的 Stack Reconciler 有致命缺陷:
- 同步遞歸:遍歷整個虛擬 DOM 樹時,一旦開始就無法停止。
- 阻塞主線程:如果組件層級很深(幾百個),一次更新可能占用 100ms+ 的 JS 執(zhí)行時間。
- 導(dǎo)致掉幀:瀏覽器需要 16.6ms 渲染一幀(60fps),而 React 長期霸占主線程,用戶點擊、動畫都會卡頓。
典型案例:一個輸入框綁定大列表更新,每次按鍵都重新渲染整個列表,造成明顯延遲。
Fiber 的目標就是:把同步不可中斷的工作,拆解成異步可中斷的小任務(wù)單元。
二、Fiber 的核心機制
1. Fiber 是什么?(數(shù)據(jù)結(jié)構(gòu) + 工作單元)
Fiber 既是數(shù)據(jù)結(jié)構(gòu),也是執(zhí)行單元:
作為數(shù)據(jù)結(jié)構(gòu):每個 React 元素對應(yīng)一個 Fiber 節(jié)點,構(gòu)成 Fiber 樹(鏈表結(jié)構(gòu),而非樹)。
// Fiber 節(jié)點的核心字段
{
tag: 5, // 節(jié)點類型(函數(shù)組件、類組件、DOM等)
key: null,
type: 'div',
return: parentFiber, // 指向父 Fiber(完成后的返回目標)
child: childFiber, // 指向第一個子 Fiber
sibling: siblingFiber,// 指向下一個兄弟 Fiber
pendingProps: {}, // 新傳入的 props
memoizedProps: {}, // 上次渲染的 props
memoizedState: null, // 上次渲染的 state(用于 Hooks)
alternate: null, // 雙緩存中的另一個 Fiber(current <-> workInProgress)
}
作為執(zhí)行單元:Fiber 節(jié)點記錄了自身的「進度信息」,React 可以在中斷后從任意 Fiber 繼續(xù)工作。
2. 雙緩存機制(Double Buffering)
React 維護兩棵 Fiber 樹:
- current 樹:當前屏幕上顯示的內(nèi)容(已提交到 DOM)。
- workInProgress 樹:在內(nèi)存中構(gòu)建的新樹,代表下一次要顯示的界面。
工作流程:
- 觸發(fā)更新時,克隆 current 樹生成 workInProgress 樹。
- 在 workInProgress 樹上進行協(xié)調(diào)(diff + 標記副作用)。
- 構(gòu)建完成后,
commitRoot將 workInProgress 樹切換為 current 樹(一次指針切換)。 - 復(fù)用
alternate屬性指向另一棵樹,節(jié)省內(nèi)存分配。
好處:可以在構(gòu)建過程中隨時放棄 workInProgress 樹,不影響用戶當前看到的界面。
3. 調(diào)度與優(yōu)先級(Scheduler)
Fiber 搭配了獨立的調(diào)度器(Scheduler),實現(xiàn)了時間切片和優(yōu)先級隊列。
- 任務(wù)拆分:將協(xié)調(diào)過程拆解為多個「工作單元」(每個 Fiber 節(jié)點的處理就是一個單元)。
- 時間切片:每次循環(huán)檢查是否還有剩余時間(
shouldYield),超時則中斷并讓出主線程。 - 優(yōu)先級機制:
- 離散事件(click、input):立即同步執(zhí)行(最高優(yōu)先級)。
- 連續(xù)事件(scroll、拖拽):下一幀之前執(zhí)行(高優(yōu)先級)。
- 數(shù)據(jù)請求(useEffect、Suspense fallback):可中斷的低優(yōu)先級。
startTransition標記的更新:最低優(yōu)先級,空閑時執(zhí)行。
簡單模擬調(diào)度流程:
// 簡化的 workLoop
function workLoop(deadline) {
let shouldYield = false;
while (nextUnitOfWork && !shouldYield) {
nextUnitOfWork = performUnitOfWork(nextUnitOfWork); // 處理一個 Fiber
shouldYield = deadline.timeRemaining() < 1; // 剩余時間不足 1ms 則中斷
}
if (nextUnitOfWork) {
requestIdleCallback(workLoop); // 有空閑時間再繼續(xù)
} else {
commitRoot(); // 全部完成,提交 DOM
}
}
requestIdleCallback(workLoop);
三、Fiber 架構(gòu)下的兩個階段
React 將渲染過程拆解為兩個截然不同的階段:
| 階段 | 執(zhí)行內(nèi)容 | 是否可中斷 | 是否執(zhí)行副作用 | 常見方法 |
|---|---|---|---|---|
| Render/Reconciliation | 構(gòu)建 Fiber 樹、計算 diff、標記副作用 | ? 可中斷 | ? | render、shouldComponentUpdate、hooks 中的更新計算 |
| Commit | 將副作用應(yīng)用到真實 DOM、執(zhí)行生命周期 | ? 不可中斷 | ? | componentDidMount、useLayoutEffect、ref 更新 |
重要區(qū)別:
- Render 階段可以被打斷(比如用戶點擊新的高優(yōu)先級事件),React 會丟棄當前 workInProgress 樹,重新開始。
- Commit 階段必須同步完成,確保 DOM 一致性和用戶看到的結(jié)果。
這也解釋了為什么 componentWillMount 和 componentWillUpdate 被標記為不安全 —— 它們可能在 Render 階段被多次調(diào)用或中斷。
四、Fiber 帶來的具體能力
- Concurrent Mode(并發(fā)模式,現(xiàn)為默認啟用):渲染和用戶輸入并行處理,不再互相阻塞。
- Suspense:等待異步數(shù)據(jù)(代碼、圖片、數(shù)據(jù))時,渲染 fallback,數(shù)據(jù)就緒后繼續(xù) Fiber 工作。
- useDeferredValue / startTransition:將低優(yōu)先級更新標記為可中斷,保障高優(yōu)先級響應(yīng)的流暢度。
- 錯誤邊界:通過
componentDidCatch捕獲子組件樹的錯誤,防止整個應(yīng)用崩潰。
五、常見面試追問與簡答
Q:Fiber 架構(gòu)下的 diff 算法有變化嗎?
A:核心策略相同(同級比較、key 復(fù)用),但實現(xiàn)上基于 Fiber 鏈表,且 diff 過程是異步可中斷的。
Q:Fiber 有打破 React 聲明式編程的范式嗎?
A:沒有。Fiber 是內(nèi)部實現(xiàn)優(yōu)化,對外 API 保持一致,開發(fā)者依然面向狀態(tài)編程。
Q:使用 Fiber 一定能提升性能嗎?
A:不一定。對于簡單應(yīng)用,F(xiàn)iber 的調(diào)度開銷可能略微增加總耗時。主要收益是在復(fù)雜交互場景(輸入框 + 大列表渲染)下保持 UI 流暢。
Q:Fiber 樹和虛擬 DOM 樹是什么關(guān)系?
A:虛擬 DOM 是 React 元素樹(每次 render 重建)。Fiber 樹是持久化的(只更新屬性),通過 alternate 復(fù)用節(jié)點,性能更高。
如果你需要進一步了解 Fiber 的副作用收集(Effect List) 或Hooks 在 Fiber 上的存儲原理,我可以繼續(xù)展開。
到此這篇關(guān)于深入理解React Fiber機制的文章就介紹到這了,更多相關(guān)React Fiber 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 深入理解React的Fiber架構(gòu)
- React 中的雙緩存 Fiber 樹機制詳解
- React Fiber 架構(gòu)解決頁面卡頓問題的全過程
- React Fiber中面試官最關(guān)心的技術(shù)話題
- React-three-fiber使用初體驗
- React超詳細講述Fiber的使用
- React?Fiber構(gòu)建源碼解析
- React?Fiber構(gòu)建completeWork源碼解析
- React?Fiber原理深入分析
- React Fiber與調(diào)和深入分析
- React Fiber源碼深入分析
- React的Fiber的實現(xiàn), Vue為什么不需要Fiber
相關(guān)文章
react-native 圓弧拖動進度條實現(xiàn)的示例代碼
本篇文章主要介紹了react-native 圓弧拖動進度條實現(xiàn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
詳解在create-react-app使用less與antd按需加載
這篇文章主要介紹了詳解在create-react-app使用less與antd按需加載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12

