成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇帶你了解 React Fiber 是什么?

開發(fā) 前端
Fiber,本意為 “纖維”,在計算機世界中則是 ”纖程“ 的意思。纖程可以看作是協(xié)程的一種,是一種 任務調度 方式。

大家好,我是前端西瓜哥。

為了提高 React 的性能,React 團隊在開發(fā) React 16 時做了底層的重構,引入了 React Fiber 的概念。

React Fiber 是什么?

Fiber,本意為 “纖維”,在計算機世界中則是 ”纖程“ 的意思。纖程可以看作是協(xié)程的一種,是一種任務調度方式。

JavaScript 是單線程的,有一個 event loop 的概念,它有一個有優(yōu)先級的任務隊列,只能按順序執(zhí)行一個任務,是不支持多個任務同時執(zhí)行的。

這種設計的好處就是不用考慮多線程導致的順序問題,并為此做一些加鎖的額外邏輯,確保執(zhí)行順序符合預期。但也因為無法使用并行能力,在 CPU 密集的場景會有性能問題, 比如一個任務耗時過長會導致其他的任務,導致用戶的交互響應發(fā)生延遲。

?React 的組件更新是 CPU 密集的操作,因為它要做對比新舊虛擬 DOM 樹的操作(diff,React 中 Reconcilation 負責),找出需要更新的內容(patch),通過打補丁的方式更新真實 DOM 樹(React 中 Renderer 負責)。當要對比的組件樹非常多時,就會發(fā)生大量的新舊節(jié)點對比,CPU 花費時間龐大,當耗時大大超過 16.6ms(一秒 60 幀的基準) 時,用戶會感覺到明顯的卡頓。

這一系列操作是通過遞歸的方式實現(xiàn)的,是 同步且不可中斷 的。因為一旦中斷,調用棧就會被銷毀,中間的狀態(tài)就丟失了。這種基于調用棧的實現(xiàn),我們稱為 Stack Reconcilation。

React 16 的一個重點工作就是優(yōu)化更新組件時大量的 CPU 計算,最后選擇了使用 “時間分片” 的方案,就是將原本要一次性做的工作,拆分成一個個異步任務,在瀏覽器空閑的時間時執(zhí)行。這種新的架構稱為 Fiber Reconcilation。

在 React 中,F(xiàn)iber 模擬之前的遞歸調用,具體通過鏈表的方式去模擬函數(shù)的調用棧,這樣就可以做到中斷調用,將一個大的更新任務,拆分成小的任務,并設置優(yōu)先級,在瀏覽器空閑的時異步執(zhí)行。

FiberNode

前面我們說到使用了鏈表的遍歷來模擬遞歸棧調用,其中鏈表的節(jié)點 React 用 FiberNode 表示。

FiberNode 其實就是虛擬 DOM,它記錄了:

  1. 節(jié)點相關類型,比如 tag 表示組件類型、type 表示元素類型等。
  2. 節(jié)點的指向。
  3. 副作用相關的屬性。
  4. lanes 是關于調度優(yōu)先級的。
function FiberNode(
tag: WorkTag,
pendingProps: mixed,
key: null | string,
mode: TypeOfMode,
) {
// Instance
this.tag = tag; // 組件類型,比如 Function/Class/Host
this.key = key; // key 唯一值,通常會在列表中使用
this.elementType = null;
this.type = null; // 元素類型,字符串或類或函數(shù),比如 "div"/ComponentFn/Class
this.stateNode = null; // 指向真實 DOM 對象
// Fiber
this.return = null; // 父 Fiber
this.child = null; // 子 Fiber 的第一個
this.sibling = null; // 下一個兄弟節(jié)點
this.index = 0; // 在同級兄弟節(jié)點中的位置
this.ref = null;
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
// Effects
this.flags = NoFlags;
this.subtreeFlags = NoFlags;
this.deletions = null;
this.lanes = NoLanes;
this.childLanes = NoLanes;
this.alternate = null;
// ...
}

Fiber 通過 return 指向父 Fiber,child 指向子 Fiber 的首位、sibling 指向下一個兄弟節(jié)點。通過它們我們其實就能拿到一個完整的結構樹。

對于:

function App() {
return (
<div className="app">
<span>hello</span>, Fiber
</div>
);
}

形成的 Fiber 樹為:

圖片

其中弧線為調用順序。紫色為 beginWork、粉色為 completeWork。beginWork 是 “遞” 的過程,而 comleteWork 則是 “歸” 的過程。

為什么不用 generator 或 async/await?

generator 和 async/await 也可以做到在函數(shù)中間暫停函數(shù)執(zhí)行的邏輯,將執(zhí)行讓出去,能做到將同步變成異步。

但 React 沒有選擇它們,這是因為:

  1. 具有傳染性,比如一個函數(shù)用了 async,調用它的函數(shù)就要加上 async,有語法開銷,此外也會有性能上的額外開銷。
  2. 無法在 generator 和 async/await 中恢復一些中間狀態(tài)。

具體見官方的 github issue 討論:

https://github.com/facebook/react/issues/7942#issuecomment-254987818。

Scheduler

圖片

做了時間分片,拆分了多個任務,React 就可以以此為基石,給任務設置優(yōu)先級。

React 實現(xiàn)了一個 Scheduler(調度器)來實現(xiàn)任務調度執(zhí)行,并單獨抽離為一個單獨的包,它會在瀏覽器有空閑的時候執(zhí)行。其實瀏覽器也提供了一個 requestIdleCallback 的 API,支持這個能力,但兼容性實在不好,React 還是自己實現(xiàn)了一套。

這個 Scheduler 支持優(yōu)先級,底層使用了 小頂堆,確保能高效拿到最快要過期的任務,然后執(zhí)行它。

小頂堆,其實就是優(yōu)先級隊列。小頂堆在結構上是一個完全二叉樹,但能保證每次從堆頂取出元素時,是最小的元素。

任務的 優(yōu)先級 分為幾種:

  1. NoPriority:無優(yōu)先級。
  2. ImmediatePriority:立即執(zhí)行。
  3. UserBlockingPriority:用戶阻塞優(yōu)先級,不執(zhí)行可能會導致用戶交互阻塞。
  4. NormalPriority:普通優(yōu)先級。
  5. LowPriority:低優(yōu)先級。
  6. IdlePriority:空閑優(yōu)先級。

React 自身也有優(yōu)先級,叫做 Lane,兩者是不同的。

結尾

React 的架構過于宏大,今天先隨便說一點吧。

總的來說,React Fiber 是在 React 16 中引入的新的架構,將原本同步不可中斷的更新,變成異步可中斷更新,將原本一個耗時的大任務做了時間分片,拆分成一個個小任務,在瀏覽器空閑的時間執(zhí)行。此外添加優(yōu)先級的概念,將一些重要的任務先執(zhí)行,比如一些用戶交互的響應函數(shù)。

一切為了更好的用戶體驗。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2021-05-20 06:57:16

RabbitMQ開源消息

2022-03-23 08:31:25

LRU 算法JavaScripLFU 緩存算法

2023-05-12 08:19:12

Netty程序框架

2021-07-28 10:02:54

建造者模式代碼

2021-07-14 08:24:23

TCPIP 通信協(xié)議

2021-06-30 00:20:12

Hangfire.NET平臺

2021-08-11 07:02:21

npm包管理器工具

2021-11-24 08:51:32

Node.js監(jiān)聽函數(shù)

2021-08-02 06:34:55

Redis刪除策略開源

2021-12-15 11:52:34

GPLLinuxGNU

2021-11-08 08:42:44

CentOS Supervisor運維

2021-07-07 07:14:48

分布式ID分布式系統(tǒng)

2022-12-20 08:22:42

CommitMuation

2020-11-10 10:48:10

JavaScript屬性對象

2021-06-04 09:56:01

JavaScript 前端switch

2021-07-08 06:30:03

Linux CPULinux 系統(tǒng)

2021-08-14 10:01:43

Python條件語句Python基礎

2021-01-29 18:41:16

JavaScript函數(shù)語法

2021-08-26 05:27:08

Base64 字節(jié)流算法

2021-02-02 18:39:05

JavaScript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产色婷婷精品综合在线播放 | 一本一道久久a久久精品蜜桃 | 国产高清视频一区 | 在线观看中文字幕视频 | 亚洲精品国产a久久久久久 午夜影院网站 | 日韩精品一区二区三区中文在线 | 超碰成人免费 | 国产免费一区二区 | 一区二区精品在线 | 国产激情一区二区三区 | 毛片一区 | 高清视频一区二区三区 | 中文字幕日韩专区 | 成人精品在线观看 | 亚洲毛片在线观看 | 久久精品国产亚洲一区二区 | 久久最新 | 91麻豆精品国产91久久久久久久久 | 91麻豆精品国产91久久久久久 | 91精品久久久 | 国产一区不卡 | 91精品久久久久久久久久 | 亚洲情视频 | 中文日韩在线 | 中文字幕一区二区三区在线视频 | 日韩中文视频 | 国产一区二区三区亚洲 | 亚洲免费观看 | 少妇特黄a一区二区三区88av | 亚洲精品电影在线观看 | 爱综合| www.久| 日韩中文在线 | 日日骚网 | 在线观看视频中文字幕 | 欧美色专区 | 国产真实乱对白精彩久久小说 | 免费福利视频一区二区三区 | 欧美久久国产精品 | 日本 欧美 国产 | 欧美精品一区二区三区在线 |