成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺談React Fiber

izhuhaodev / 3175人閱讀

摘要:因為版本將真正廢棄這三生命周期到目前為止,的渲染機制遵循同步渲染首次渲染,更新時更新時卸載時期間每個周期函數(shù)各司其職,輸入輸出都是可預(yù)測,一路下來很順暢。通過進一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個生命周期函數(shù)都發(fā)生在虛擬的構(gòu)建期間,也就是之前。

背景

前段時間準備前端招聘事項,復(fù)習前端React相關(guān)知識;復(fù)習React16新的生命周期:棄用了componentWillMount、componentWillReceivePorpscomponentWillUpdate三個生命周期, 新增了getDerivedStateFromPropsgetSnapshotBeforeUpdate來代替棄用的三個鉤子函數(shù)。
發(fā)現(xiàn)React生命周期的文章很少說到 React 官方為什么要棄用這三生命周期的原因, 查閱相關(guān)資料了解到根本原因是V16版本重構(gòu)核心算法架構(gòu):React Fiber;查閱資料過程中對React Fiber有了一定了解,本文就相關(guān)資料整理出個人對Fiber的理解, 與大家一起簡單認識下 React Fiber

React Fiber是什么?

官方的一句話解釋是“React Fiber是對核心算法的一次重新實現(xiàn)”。Fiber 架構(gòu)調(diào)整很早就官宣了,但官方經(jīng)過兩年時間才在V16版本正式發(fā)布。官方概念解釋太籠統(tǒng), 其實簡單來說 React Fiber 是一個新的任務(wù)調(diào)和器(Reconciliation), 本文后續(xù)將詳細解釋。

為什么叫 “Fiber”?

大家應(yīng)該都清楚進程(Process)和線程(Thread)的概念,進程是操作系統(tǒng)分配資源的最小單元,線程是操作系統(tǒng)調(diào)度的最小單元,在計算機科學中還有一個概念叫做Fiber,英文含義就是“纖維”,意指比Thread更細的線,也就是比線程(Thread)控制得更精密的并發(fā)處理機制。
上面說的Fiber和React Fiber不是相同的概念,但是,React團隊把這個功能命名為Fiber,含義也是更加緊密的處理機制,比Thread更細。

Fiber 架構(gòu)解決了什么問題?

為什么官方要花2年多的時間來重構(gòu)React 核心算法?
首先要從Fiber算法架構(gòu)前 React 存在的問題說起!說起React算法架構(gòu)避不開“Reconciliaton”。

Reconciliation

React 官方核心算法名稱是 Reconciliation , 中文翻譯是“協(xié)調(diào)”!React diff 算法的實現(xiàn) 就與之相關(guān)。
先簡單回顧下React Diff: React首創(chuàng)了“虛擬DOM”概念, “虛擬DOM”能火并流行起來主要原因在于該概念對前端性能優(yōu)化的突破性創(chuàng)新;
稍微了解瀏覽器加載頁面原理的前端同學都知道網(wǎng)頁性能問題大都出現(xiàn)在DOM節(jié)點頻繁操作上;
而React通過“虛擬DOM” + React Diff算法保證了前端性能;

傳統(tǒng)Diff算法

通過循環(huán)遞歸對節(jié)點進行依次對比,算法復(fù)雜度達到 O(n^3) ,n是樹的節(jié)點數(shù),這個有多可怕呢?——如果要展示1000個節(jié)點,得執(zhí)行上億次比較。。即便是CPU快能執(zhí)行30億條命令,也很難在一秒內(nèi)計算出差異。

React Diff算法

將Virtual DOM樹轉(zhuǎn)換成actual DOM樹的最少操作的過程 稱為 協(xié)調(diào)(Reconciliaton)。
React Diff三大策略 :
1.tree diff;
2.component diff;
3.element diff;
PS: 之前H5開發(fā)遇到的State 中變量更新但視圖未更新的Bug就是element diff檢測導(dǎo)致。解決方案:1.兩種業(yè)務(wù)場景下的DOM節(jié)點盡量避免雷同; 2.兩種業(yè)務(wù)場景下的DOM節(jié)點樣式避免雷同;

在V16版本之前 協(xié)調(diào)機制Stack reconciler, V16版本發(fā)布Fiber 架構(gòu)后是 Fiber reconciler。

Stack reconciler Stack reconciler 源碼
// React V15: react/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
/**
 * ------------------ The Life-Cycle of a Composite Component ------------------
 *
 * - constructor: Initialization of state. The instance is now retained.
 *   - componentWillMount
 *   - render
 *   - [children"s constructors]          // 子組件constructor()
 *     - [children"s componentWillMount and render]   // 子組件willmount render
 *     - [children"s componentDidMount]  // 子組件先于父組件完成掛載didmount
 *     - componentDidMount
 *
 *       Update Phases:
 *       - componentWillReceiveProps (only called if parent updated)
 *       - shouldComponentUpdate
 *         - componentWillUpdate
 *           - render
 *           - [children"s constructors or receive props phases]
 *         - componentDidUpdate
 *
 *     - componentWillUnmount
 *     - [children"s componentWillUnmount]
 *   - [children destroyed]
 * - (destroyed): The instance is now blank, released by React and ready for GC.
 *
 * -----------------------------------------------------------------------------
Stack reconciler 存在的問題

Stack reconciler的工作流程很像函數(shù)的調(diào)用過程。父組件里調(diào)子組件,可以類比為函數(shù)的遞歸(這也是為什么被稱為stack reconciler的原因)。
在setState后,react會立即開始reconciliation過程,從父節(jié)點(Virtual DOM)開始遍歷,以找出不同。將所有的Virtual DOM遍歷完成后,reconciler才能給出當前需要修改真實DOM的信息,并傳遞給renderer,進行渲染,然后屏幕上才會顯示此次更新內(nèi)容。
對于特別龐大的DOM樹來說,reconciliation過程會很長(x00ms),在這期間,主線程是被js占用的,因此任何交互、布局、渲染都會停止,給用戶的感覺就是頁面被卡住了。

網(wǎng)友測試使用React V15,當DOM節(jié)點數(shù)量達到100000時, 加載頁面時間竟然要7秒;詳情
當然以上極端情況一般不會出現(xiàn),官方為了解決這種特殊情況。在Fiber 架構(gòu)中使用了Fiber reconciler。

Fiber reconciler

原來的React更新任務(wù)是采用遞歸形式,那么現(xiàn)在如果任務(wù)想中斷, 在遞歸中是很難處理, 所以React改成了大循環(huán)模式,修改了生命周期也是因為任務(wù)可中斷。

Fiber reconciler 源碼

React的相關(guān)代碼都放在packages文件夾里。(PS: 源碼一直在更新,以下路徑有時效性不一定準確)

├── packages --------------------- React實現(xiàn)的相關(guān)代碼
│   ├── create-subscription ------ 在組件里訂閱額外數(shù)據(jù)的工具
│   ├── events ------------------- React事件相關(guān)
│   ├── react -------------------- 組件與虛擬DOM模型
│   ├── react-art ---------------- 畫圖相關(guān)庫
│   ├── react-dom ---------------- ReactDom
│   ├── react-native-renderer ---- ReactNative
│   ├── react-reconciler --------- React調(diào)制器
│   ├── react-scheduler ---------- 規(guī)劃React初始化,更新等等
│   ├── react-test-renderer ------ 實驗性的React渲染器
│   ├── shared ------------------- 公共代碼
│   ├── simple-cache-provider ---- 為React應(yīng)用提供緩存

這里面我們主要關(guān)注 reconciler 這個模塊, packages/react-reconciler/src

├── react-reconciler ------------------------ reconciler相關(guān)代碼
│   ├── ReactFiberReconciler.js ------------- 模塊入口
├─ Model ----------------------------------------
│   ├── ReactFiber.js ----------------------- Fiber相關(guān)
│   ├── ReactUpdateQueue.js ----------------- state操作隊列
│   ├── ReactFiberRoot.js ------------------- RootFiber相關(guān)
├─ Flow -----------------------------------------
│   ├── ReactFiberScheduler.js -------------- 1.總體調(diào)度系統(tǒng)
│   ├── ReactFiberBeginWork.js -------------- 2.Fiber解析調(diào)度
│   ├── ReactFiberCompleteWork.js ----------- 3.創(chuàng)建DOM 
│   ├── ReactFiberCommitWork.js ------------- 4.DOM布局
├─ Assist ---------------------------------------
│   ├── ReactChildFiber.js ------------------ children轉(zhuǎn)換成subFiber
│   ├── ReactFiberTreeReflection.js --------- 檢索Fiber
│   ├── ReactFiberClassComponent.js --------- 組件生命周期
│   ├── stateReactFiberExpirationTime.js ---- 調(diào)度器優(yōu)先級
│   ├── ReactTypeOfMode.js ------------------ Fiber mode type
│   ├── ReactFiberHostConfig.js ------------- 調(diào)度器調(diào)用渲染器入口
Fiber reconciler 優(yōu)化思路

Fiber reconciler 使用了scheduling(調(diào)度)這一過程, 每次只做一個很小的任務(wù),做完后能夠“喘口氣兒”,回到主線程看下有沒有什么更高優(yōu)先級的任務(wù)需要處理,如果有則先處理更高優(yōu)先級的任務(wù),沒有則繼續(xù)執(zhí)行(cooperative scheduling 合作式調(diào)度)。

網(wǎng)友測試使用React V16,當DOM節(jié)點數(shù)量達到100000時, 頁面能正常加載,輸入交互也正常了;詳情

所以Fiber 架構(gòu)就是用 異步的方式解決舊版本 同步遞歸導(dǎo)致的性能問題。

Fiber 核心算法

編程最重要的是思想而不是代碼,本段主要理清Fiber架構(gòu)內(nèi)核算法的編碼思路;

Fiber 源碼解析

之前一個師弟問我關(guān)于Fiber的小問題:
Fiber 框架是否會自動給 Fiber Node打上優(yōu)先級?
如果給Fiber Node打上的是async, 是否會給給它設(shè)置 expirationTime?
帶著以上問題看源碼, 結(jié)論:
框架給每個 Fiber Node 打上優(yōu)先級(nowork, sync, async), 不管是sync 還是 async都會給 該Fiber Node 設(shè)置expirationTime, expirationTime 越小優(yōu)先級越高。

個人閱讀源碼細節(jié)就不放了, 因為發(fā)現(xiàn)網(wǎng)上有更系統(tǒng)的Fiber 源碼文章,雖然官方源碼已更新至Flow語法, 但算法并沒太大改變:
React Fiber源碼分析 (介紹)
React Fiber源碼分析 第一篇
React Fiber源碼分析 第二篇(同步模式)
React Fiber源碼分析 第三篇(異步狀態(tài))

優(yōu)先級

module.exports = {
  NoWork: 0, // No work is pending.
  SynchronousPriority: 1, // For controlled text inputs. Synchronous side-effects.
  AnimationPriority: 2, // Needs to complete before the next frame.
  HighPriority: 3, // Interaction that needs to complete pretty soon to feel responsive.
  LowPriority: 4, // Data fetching, or result from updating stores.
  OffscreenPriority: 5, // Won"t be visible but do the work in case it becomes visible.
};

React Fiber 每個工作單元運行時有6種優(yōu)先級:
synchronous 與之前的Stack reconciler操作一樣,同步執(zhí)行
task 在next tick之前執(zhí)行
animation 下一幀之前執(zhí)行
high 在不久的將來立即執(zhí)行
low 稍微延遲(100-200ms)執(zhí)行也沒關(guān)系
offscreen 下一次render時或scroll時才執(zhí)行

生命周期

生命周期函數(shù)也被分為2個階段了:

// 第1階段 render/reconciliation
componentWillMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate

// 第2階段 commit
componentDidMount
componentDidUpdate
componentWillUnmount

第1階段的生命周期函數(shù)可能會被多次調(diào)用,默認以low優(yōu)先級 執(zhí)行,被高優(yōu)先級任務(wù)打斷的話,稍后重新執(zhí)行。

Fiber 架構(gòu)對React開發(fā)影響

本段主要探討React V16 后Fiber架構(gòu)對我們使用React業(yè)務(wù)編程的影響有哪些?實際編碼需要注意哪些內(nèi)容。

1.不使用官方宣布棄用的生命周期。

為了兼容舊代碼,官方并沒有立即在V16版本廢棄三生命周期, 用新的名字(帶上UNSAFE)還是能使用。 建議使用了V16+版本的React后就不要再使用廢棄的三生命周期。
因為React 17版本將真正廢棄這三生命周期:

到目前為止(React 16.4),React的渲染機制遵循同步渲染: 
1) 首次渲染: willMount > render > didMount,
2) props更新時: receiveProps > shouldUpdate > willUpdate > render > didUpdate
3) state更新時: shouldUpdate > willUpdate > render > didUpdate
3) 卸載時: willUnmount
期間每個周期函數(shù)各司其職,輸入輸出都是可預(yù)測,一路下來很順暢。
BUT 從React 17 開始,渲染機制將會發(fā)生顛覆性改變,這個新方式就是 Async Render。
首先,async render不是那種服務(wù)端渲染,比如發(fā)異步請求到后臺返回newState甚至新的html,這里的async render還是限制在React作為一個View框架的View層本身。
通過進一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個生命周期函數(shù)都發(fā)生在虛擬dom的構(gòu)建期間,也就是render之前。在將來的React 17中,在dom真正render之前,React中的調(diào)度機制可能會不定期的去查看有沒有更高優(yōu)先級的任務(wù),如果有,就打斷當前的周期執(zhí)行函數(shù)(哪怕已經(jīng)執(zhí)行了一半),等高優(yōu)先級任務(wù)完成,再回來重新執(zhí)行之前被打斷的周期函數(shù)。這種新機制對現(xiàn)存周期函數(shù)的影響就是它們的調(diào)用時機變的復(fù)雜而不可預(yù)測,這也就是為什么”UNSAFE”。
作者:辰辰沉沉大辰沉
來源:CSDN
2.注意Fiber 優(yōu)先級導(dǎo)致的bug;

了解Fiber原理后, 業(yè)務(wù)開發(fā)注意高優(yōu)先級任務(wù)頻率,避免出現(xiàn)低優(yōu)先級任務(wù)延遲太久執(zhí)行或永不執(zhí)行bug(starvation:低優(yōu)先級餓死)。

3.業(yè)務(wù)邏輯實現(xiàn)別太依賴生命周期鉤子函數(shù);

在Fiber架構(gòu)中,task 有可能被打斷,需要重新執(zhí)行,某些依賴生命周期實現(xiàn)的業(yè)務(wù)邏輯可能會受到影響。

參考文檔
React 新生命周期;
深入理解進程和線程;
完全理解React Fiber;
React Fiber;
如何閱讀大型項目源碼;
React 源碼解析;
React Fiber 源碼解析;
React Fiber 是什么?
React diff 算法策略和實現(xiàn)
React 新引擎, React Fiber 是什么?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106653.html

相關(guān)文章

  • Deep In React淺談 React Fiber 架構(gòu)(一)

    摘要:在上面我們已經(jīng)知道瀏覽器是一幀一幀執(zhí)行的,在兩個執(zhí)行幀之間,主線程通常會有一小段空閑時間,可以在這個空閑期調(diào)用空閑期回調(diào),執(zhí)行一些任務(wù)。另外由于這些堆棧是可以自己控制的,所以可以加入并發(fā)或者錯誤邊界等功能。 文章首發(fā)于個人博客 前言 2016 年都已經(jīng)透露出來的概念,這都 9102 年了,我才開始寫 Fiber 的文章,表示慚愧呀。不過現(xiàn)在好的是關(guān)于 Fiber 的資料已經(jīng)很豐富了,...

    Jiavan 評論0 收藏0
  • 淺談ReactFiber

    摘要:什么是每一個都有一個對應(yīng)的,記錄這個節(jié)點的各種狀態(tài),是一鏈表的結(jié)構(gòu)的串聯(lián)起來。 1. 什么是fiber 每一個ReactElement都有一個對應(yīng)的fiber, 記錄這個節(jié)點的各種狀態(tài), fiber是一鏈表的結(jié)構(gòu)的串聯(lián)起來。showImg(https://segmentfault.com/img/bVbqVZR?w=540&h=708); 2. Fiber的組成 export type...

    yibinnn 評論0 收藏0
  • 淺談reacthooks閉包陷阱

      本文不會過多講解基礎(chǔ)知識,更多說的是在使用useRef如何能擺脫 這個 閉包陷阱 ?  react hooks 的閉包陷阱 基本每個開發(fā)員都有遇見,這是很令人抓狂的?! ?以下react示范demo,均為react 16.8.3 版本)  列一個具體的場景:  functionApp(){   const[count,setCount]=useState(1);   useEffect(()=...

    3403771864 評論0 收藏0
  • React系列——React Fiber 架構(gòu)介紹資料匯總(翻譯+中文資料)

    摘要:它的主體特征是增量渲染能夠?qū)秩竟ぷ鞣指畛蓧K,并將其分散到多個幀中。實際上,這樣做可能會造成浪費,導(dǎo)致幀丟失并降低用戶體驗。當一個函數(shù)被執(zhí)行時,一個新的堆??蚣鼙惶砑拥蕉褩V?。該堆??虮硎居稍摵瘮?shù)執(zhí)行的工作。 原文 react-fiber-architecture 介紹 React Fibre是React核心算法正在進行的重新實現(xiàn)。它是React團隊兩年多的研究成果。 React ...

    taohonghui 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<