91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react?fiber執行原理是什么

發布時間:2022-11-07 10:38:23 來源:億速云 閱讀:116 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“react fiber執行原理是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“react fiber執行原理是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

為什么要使用fiber,要解決什么問題?

react16 引入 Fiber 架構之前,react 會采用遞歸方法對比兩顆虛擬DOM樹,找出需要改動的節點,然后同步更新它們,這個過程 react 稱為reconcilation(協調)。在reconcilation期間,react 會同步執行操作,提交到真實 DOM 的更改,會一直占著瀏覽器的資源,不能中斷,中斷后就不能恢復,使得我們一些用戶操作定時器等等事件無法得到響應,是一個非常糟糕的用戶體驗。

所以我們要解決的問題就是:解決React主線程長時間占用的一個問題。 這個時候,就引入了Fiber架構。

fiber是什么?

Fiber 可以理解為是一個執行單元,也可以理解為是一種數據結構。每一個React元素都對應一個fiber對象,我們先看看fiber中的屬性:

function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // 作為靜態數據結構的屬性
  this.tag = tag;	     // Fiber對應組件的類型 Function/Class/Host...
  this.key = key;	     // key屬性
  this.elementType = null;   // 大部分情況同type,某些情況不同,比如FunctionComponent使用React.memo包裹
  this.type = null;					// 對于 FunctionComponent,指函數本身,對于ClassComponent,指class,對于HostComponent,指DOM節點tagName
  this.stateNode = null;		// Fiber對應的真實DOM節點
  // 用于連接其他Fiber節點形成Fiber樹
  this.parent = null;		// 指向父級Fiber節點
  this.child = null;		// 指向子Fiber節點
  this.sibling = null;	// 指向右邊第一個兄弟Fiber節點
  this.index = 0;
  this.ref = null;
  // 作為動態的工作單元的屬性 —— 保存本次更新造成的狀態改變相關信息
  this.pendingProps = pendingProps;
  this.memoizedProps = null;
  this.updateQueue = null;		// class 組件 Fiber 節點上的多個 Update 會組成鏈表并被包含在 fiber.updateQueue 中。 函數組件則是存儲 useEffect 的 effect 的環狀鏈表。
  this.memoizedState = null;	// hook 組成單向鏈表掛載的位置
  this.dependencies = null;
  this.mode = mode;
  // Effects
  this.flags = NoFlags;
  this.subtreeFlags = NoFlags;
  this.deletions = null;
  // 調度優先級相關
  this.lanes = NoLanes;
  this.childLanes = NoLanes;
  // 指向該fiber在另一次更新時對應的fiber
  this.alternate = null;
}

數據結構

React Fiber 就是采用鏈表實現的,主要就是通過以下這幾個屬性表示:

  this.parent = null;		// 指向父級Fiber節點
  this.child = null;		// 指向子Fiber節點
  this.sibling = null;	// 指向右邊第一個兄弟Fiber節點

假如我們要渲染下面這個元素樹:

<div>
    <h2>
        <p>
            <a></a>
        </p>
    </h2>
    <h3></h3>
</div>

我們看一下它的Fiber結構樹:

react?fiber執行原理是什么

每個fiber元素都有這三個屬性,觀察上面圖發現:

  • parent:指向父級Fiber節點:

  • child:指向子Fiber節點

  • sibling:指向右邊的兄弟節點

執行單元

我們可以把每個fiber當做一個執行單元,每次執行完一個執行單元。React會去檢測還剩多少時間,如果沒有時間就將控制權讓給瀏覽器,如果還有時間就去執行下一個執行單元。
這里就涉及到了一個問題,react如何和瀏覽器進行控制權的交接,瀏覽器何時空閑呢?。我們先來了解一下瀏覽器的工作:

瀏覽器工作:

在瀏覽器中,我們所看到的頁面是一幀一幀畫出來的,渲染的幀率與設備的刷新率保持一致。通常情況下,我們的設備都是60Hz,也就是說,1s屏幕會刷新60次。當每秒內繪制的幀數(FPS)超過60時,頁面渲染是流暢的,當幀數小于60時,會明顯感受到卡頓。下面來看完整的一幀中,瀏覽器具體做了哪些事情:

react?fiber執行原理是什么

  • 首先需要處理輸入事件,能夠讓用戶得到最早的反饋

  • 接下來是處理定時器,需要檢查定時器是否到時間,并執行對應的回調

  • 接下來處理 Begin Frame(開始幀),即每一幀的事件,包括 window.resizescrollmedia query change

  • 接下來執行請求動畫幀 requestAnimationFrame(rAF),即在每次繪制之前,會執行 rAF 回調

  • 緊接著進行 Layout 操作,包括計算布局和更新布局,即這個元素的樣式是怎樣的,它應該在頁面如何展示

  • 接著進行 Paint 操作,得到樹中每個節點的尺寸與位置等信息,瀏覽器針對每個元素進行內容填充

  • 到這時以上的六個階段都已經完成了,接下來處于空閑階段(Idle Peroid),可以在這時執行 requestIdleCallback 里注冊的任務

這樣我們把工作單元的任務放到requestIdleCallback回調當中,如果瀏覽器處理完上述的任務(布局和繪制之后),還有盈余時間,這個時候就可以執行我們的工作單元了。每次執行完一個執行單元。React會去檢測還剩多少時間,如果沒有時間就將控制權讓給瀏覽器。直至,React和瀏覽器通過合作式調度完美配合,實現高性能應用。

Fiber執行原理

從根節點開始調度和渲染可以分為兩個階段:rendercommit。 先來了解下這幾個關鍵名詞:

workInProgress tree:

workInProgress 代表當前正在執行更新的 Fiber 樹。在 setState或者渲染 后,會構建一顆 Fiber 樹,也就是 workInProgress tree

currentFiber tree:

首次渲染之后,React 會生成一個對應于 UI 渲染的 fiber 樹,稱之為 current 樹。在新一輪更新時 workInProgress tree 再重新構建,新workInProgress的節點通過 alternate 屬性和 currentFiber 的節點建立聯系。

Effects list:

effect list 可以理解為是一個存儲 effect 副作用列表容器。

render階段:

render階段中,會找到所有節點的變更,比如說節點新增,編輯,刪除等等。這些變更React稱之為副作用effect。在這個階段中,也可以認為是diff階段,主要就是對比currentFiber treeworkInProgress tree之間的差異,然后打上標記

在這個階段,任務是可以終止的。React 可以根據當前可用的時間片處理一個或多個 fiber 節點,并且得益于 fiber 對象中存儲的元素上下文信息以及構成的鏈表結構,使其能夠將執行到一半的工作仍保存在內存的鏈表中。在重新獲得控制權后,又可以根據保存在內存中的上下文信息快速找到停止的fiber節點,然后繼續工作執行工作單元。

遍歷節點過程:

遍歷Fiber tree時采用的是后序遍歷方法

  • 從頂部開始遍歷

  • 如果有child節點,且還未遍歷,遍歷child節點

  • 如果有child節點,且已經遍歷過,則遍歷sibling節點。

  • 如果沒有child節點,返回父節點

  • 如果最后返回的節點為頂部,表示所有節點遍歷完成。

react?fiber執行原理是什么

收集effect list:

在遍歷的過程中,我們會去收集所有變更的節點產出的effect,每個effect通過鏈表的方式鏈接。每個 fiber 有兩個屬性

  • firstEffect:指向第一個有副作用的子fiber

  • lastEffect:指向最后一個有副作用的子fiber

中間的使用nextEffect做成一個單鏈表。

commit階段:

render階段不同,commit階段是同步操作的。

為什么commit必須是同步的操作的?

因為在commit階段是更新真實的dom,所以更新dom不可能一點一點去更新,這樣用戶體驗會極差。所以commit階段必須是同步執行,一次更新到位。

首先的事情是遍歷effect-list列表,拿到每一個 effect 存儲的信息,根據副作用類型 effectTag 執行相應的處理并提交更新到真正的 DOM。所有的effects都會在layout phase階段之前被處理。當該階段執行結束時,workInProgress樹會被替換成current樹。到這里,根據收集到的變更信息完成了刷新操作。

讀到這里,這篇“react fiber執行原理是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

睢宁县| 昌平区| 新安县| 苏州市| 卫辉市| 思茅市| 祥云县| 广汉市| 荣成市| 伊金霍洛旗| 玛多县| 班戈县| 周口市| 静海县| 德庆县| 鄂托克前旗| 达州市| 阿坝| 怀宁县| 泸西县| 灵石县| 万载县| 宁强县| 凤山市| 鄂托克旗| 扬中市| 富阳市| 陈巴尔虎旗| 祁阳县| 肇庆市| 广元市| 瑞昌市| 根河市| 伊吾县| 城步| 太白县| 江孜县| 轮台县| 远安县| 绥滨县| 灵石县|