国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React Fiber 原理介紹

leap_frog / 2545人閱讀

摘要:如果運算持續占用主線程,頁面就沒法得到及時的更新。三解題思路解決主線程長時間被運算占用這一問題的基本思路,是將運算切割為多個步驟,分批完成。這顆新樹每生成一個新的節點,都會將控制權交回給主線程,去檢查有沒有優先級更高的任務需要執行。

歡迎關注我的公眾號睿Talk,獲取我最新的文章:

一、前言

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

二、React 15 的問題

在頁面元素很多,且需要頻繁刷新的場景下,React 15 會出現掉幀的現象。請看以下例子:
https://claudiopro.github.io/...

其根本原因,是大量的同步計算任務阻塞了瀏覽器的 UI 渲染。默認情況下,JS 運算、頁面布局和頁面繪制都是運行在瀏覽器的主線程當中,他們之間是互斥的關系。如果 JS 運算持續占用主線程,頁面就沒法得到及時的更新。當我們調用setState更新頁面的時候,React 會遍歷應用的所有節點,計算出差異,然后再更新 UI。整個過程是一氣呵成,不能被打斷的。如果頁面元素很多,整個過程占用的時機就可能超過 16 毫秒,就容易出現掉幀的現象。

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

三、解題思路

解決主線程長時間被 JS 運算占用這一問題的基本思路,是將運算切割為多個步驟,分批完成。也就是說在完成一部分任務之后,將控制權交回給瀏覽器,讓瀏覽器有時間進行頁面的渲染。等瀏覽器忙完之后,再繼續之前未完成的任務。

舊版 React 通過遞歸的方式進行渲染,使用的是 JS 引擎自身的函數調用棧,它會一直執行到棧空為止。而Fiber實現了自己的組件調用棧,它以鏈表的形式遍歷組件樹,可以靈活的暫停、繼續和丟棄執行的任務。實現方式是使用了瀏覽器的requestIdleCallback這一 API。官方的解釋是這樣的:

window.requestIdleCallback()會在瀏覽器空閑時期依次調用函數,這就可以讓開發者在主事件循環中執行后臺或低優先級的任務,而且不會對像動畫和用戶交互這些延遲觸發但關鍵的事件產生影響。函數一般會按先進先調用的順序執行,除非函數在瀏覽器調用它之前就到了它的超時時間。

有了解題思路后,我們再來看看 React 具體是怎么做的。

四、React 的答卷

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

Virtual DOM 層,描述頁面長什么樣。

Reconciler 層,負責調用組件生命周期方法,進行 Diff 運算等。

Renderer 層,根據不同的平臺,渲染出相應的頁面,比較常見的是 ReactDOM 和 ReactNative。

這次改動最大的當屬 Reconciler 層了,React 團隊也給它起了個新的名字,叫Fiber Reconciler。這就引入另一個關鍵詞:Fiber。

Fiber 其實指的是一種數據結構,它可以用一個純 JS 對象來表示:

const fiber = {
    stateNode,    // 節點實例
    child,        // 子節點
    sibling,      // 兄弟節點
    return,       // 父節點
}

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

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

為了達到這種效果,就需要有一個調度器 (Scheduler) 來進行任務分配。任務的優先級有六種:

synchronous,與之前的Stack Reconciler操作一樣,同步執行

task,在next tick之前執行

animation,下一幀之前執行

high,在不久的將來立即執行

low,稍微延遲執行也沒關系

offscreen,下一次render時或scroll時才執行

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

Fiber Reconciler 在執行過程中,會分為 2 個階段。

階段一,生成 Fiber 樹,得出需要更新的節點信息。這一步是一個漸進的過程,可以被打斷。

階段二,將需要更新的節點一次過批量更新,這個過程不能被打斷。

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

五、Fiber 樹

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,源碼層面其實就是干了一件遞歸改循環的事情,日后有機會的話,我再結合源碼作進一步的介紹。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/101991.html

相關文章

  • React系列——React Fiber 架構介紹資料匯總(翻譯+中文資料)

    摘要:它的主體特征是增量渲染能夠將渲染工作分割成塊,并將其分散到多個幀中。實際上,這樣做可能會造成浪費,導致幀丟失并降低用戶體驗。當一個函數被執行時,一個新的堆棧框架被添加到堆棧中。該堆棧框表示由該函數執行的工作。 原文 react-fiber-architecture 介紹 React Fibre是React核心算法正在進行的重新實現。它是React團隊兩年多的研究成果。 React ...

    taohonghui 評論0 收藏0
  • React Fiber 漸進式遍歷詳解

    摘要:今天將手寫一個,詳細講解遍歷鏈的實現方式。可以看到循環的結束條件是當前處理的節點等于根節點。下面再來看看怎么結合,實現漸進式遍歷。 歡迎關注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 之前寫的一篇文章,React Fiber 原理介紹,介紹了 React Fiber 的實現原理,其中的關...

    GraphQuery 評論0 收藏0
  • 淺談React Fiber

    摘要:因為版本將真正廢棄這三生命周期到目前為止,的渲染機制遵循同步渲染首次渲染,更新時更新時卸載時期間每個周期函數各司其職,輸入輸出都是可預測,一路下來很順暢。通過進一步觀察可以發現,預廢棄的三個生命周期函數都發生在虛擬的構建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時間準備前端招聘事項...

    izhuhaodev 評論0 收藏0
  • React16性能改善的原理(二)

    摘要:接下來我們就是正式的工作了,用循環從某個節點開始遍歷樹。最后一步判斷全局變量是否存在,如果存在則把這次遍歷樹產生的所有更新一次更新到真實的上去。 前情提要 上一篇我們提到如果 setState 之后,虛擬 dom diff 比較耗時,那么導致瀏覽器 FPS 降低,使得用戶覺得頁面卡頓。那么 react 新的調度算法就是把原本一次 diff 的過程切分到各個幀去執行,使得瀏覽器在 dif...

    guqiu 評論0 收藏0

發表評論

0條評論

leap_frog

|高級講師

TA的文章

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