React Fiber 原理介紹

2021-09-12 16:41:35 字數 2346 閱讀 6255

在 react fiber 架構面世一年多後,最近 react 又發布了最新版 16.8.0,又一激動人心的特性:react hooks 正式上線,讓我公升級 react 的意願越來越強烈了。在公升級之前,不妨回到原點,了解下人才濟濟的 react 團隊為什麼要大費周章,重寫 react 架構,而 fiber 又是個什麼概念。

在頁面元素很多,且需要頻繁重新整理的場景下,react 15 會出現掉幀的現象。請看以下例子:

其根本原因,是大量的計算任務阻塞了瀏覽器的 ui 渲染。預設情況下,js 運算、頁面布局和頁面繪製都是執行在瀏覽器的主線程當中,他們之間是互斥的關係。如果 js 運算持續占用主線程,頁面就沒法得到及時的更新。

針對這一問題,react 團隊從框架層面對 web 頁面的執行機制做了優化,得到很好的效果。

解決主線程長時間被 js 運算占用這一問題的基本思路,是將運算切割為多個步驟,分批完成。也就是說在完成一部分任務之後,將控制權交回給瀏覽器,讓瀏覽器有時間進行頁面的渲染。等瀏覽器忙完之後,再繼續之前未完成的任務。為了達到這個效果,需要借助瀏覽器的requestidlecallback這一 api。官方的解釋是這樣:

window.requestidlecallback()會在瀏覽器空閒時期依次呼叫函式, 這就可以讓開發者在主事件迴圈中執行後台或低優先順序的任務,而且不會對像動畫和使用者互動這樣延遲觸發而且關鍵的事件產生影響。函式一般會按先進先呼叫的順序執行,除非函式在瀏覽器呼叫它之前就到了它的超時時間。
有了解題思路後,我們再來看看 react 具體是怎麼做的。

react 框架內部的運作可以分為 3 層:

fiber 其實指的是一種資料結構,它可以用乙個純 js 物件來表示:

const fiber =
為了加以區分,以前的 reconciler 被命名為stack reconciler。stack reconciler 運作的過程是不能被打斷的,必須一條道走到黑:

而 fiber reconciler 每執行一段時間,都會將控制權交回給瀏覽器,可以分段執行:

為了達到這種效果,就需要有乙個排程器 (scheduler) 來進行任務分配。任務的優先順序有六種:

優先順序高的任務(如鍵盤輸入)可以打斷優先順序低的任務(如diff)的執行,從而更快的生效。

fiber reconciler 在執行過程中,會分為 2 個階段。

階段一可被打斷的特性,讓優先順序更高的任務先執行,從框架層面大大降低了頁面掉幀的概率。

fiber reconciler 在階段一進行 diff 計算的時候,會生成一棵 fiber 樹。這棵樹是在 virtual dom 樹的基礎上增加額外的資訊來生成的,它本質來說是乙個鍊錶。

fiber 樹在首次渲染的時候會一次過生成。在後續需要 diff 的時候,會根據已有樹和最新 virtual dom 的資訊,生成一棵新的樹。這顆新樹每生成乙個新的節點,都會將控制權交回給主線程,去檢查有沒有優先順序更高的任務需要執行。如果沒有,則繼續構建樹的過程:

如果過程中有優先順序更高的任務需要進行,則 fiber reconciler 會丟棄正在生成的樹,在空閒的時候再重新執行一遍。

在構造 fiber 樹的過程中,fiber reconciler 會將需要更新的節點資訊儲存在effect list當中,在階段二執行的時候,會批量更新相應的節點。

本文從 react 15 存在的問題出發,介紹 react fiber 解決問題的思路,並介紹了 fiber reconciler 的工作流程。從stack reconcilerfiber reconciler,原始碼層面其實就是幹了一件遞迴改迴圈的事情,日後有機會的話,我再結合原始碼作進一步的介紹。

React Fiber 原理介紹

在 react fiber 架構面世一年多後,最近 react 又發布了最新版 16.8.0,又一激動人心的特性 react hooks 正式上線,讓我公升級 react 的意願越來越強烈了。在公升級之前,不妨回到原點,了解下人才濟濟的 react 團隊為什麼要大費周章,重寫 react 架構,而 ...

React Fiber 原理介紹

在 react fiber 架構面世一年多後,最近 react 又發布了最新版 16.8.0,又一激動人心的特性 react hooks 正式上線,讓我公升級 react 的意願越來越強烈了。在公升級之前,不妨回到原點,了解下人才濟濟的 react 團隊為什麼要大費周章,重寫 react 架構,而 ...

Redis原理介紹

redis是乙個基於key value的快取記憶體系統,類似於memcached,但是支援更複雜的資料結構list set sortedset,並且有持久化的功能。由於近期工作很多地方都用到了它,所以花了不少時間來閱讀文章 編碼實驗,了解一下 redis 都能做些什麼,能有什麼樣的效能表現。首先遇到...