日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
面試官:說(shuō)說(shuō)對(duì)React Fiber架構(gòu)的理解?解決了什么問(wèn)題?

本文轉(zhuǎn)載自微信公眾號(hào)「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請(qǐng)聯(lián)系JS每日一題公眾號(hào)。

公司主營(yíng)業(yè)務(wù):成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出合川免費(fèi)做網(wǎng)站回饋大家。

一、問(wèn)題

JavaScript引擎和頁(yè)面渲染引擎兩個(gè)線程是互斥的,當(dāng)其中一個(gè)線程執(zhí)行時(shí),另一個(gè)線程只能掛起等待

如果 JavaScript 線程長(zhǎng)時(shí)間地占用了主線程,那么渲染層面的更新就不得不長(zhǎng)時(shí)間地等待,界面長(zhǎng)時(shí)間不更新,會(huì)導(dǎo)致頁(yè)面響應(yīng)度變差,用戶可能會(huì)感覺(jué)到卡頓

而這也正是 React 15 的 Stack Reconciler所面臨的問(wèn)題,當(dāng) React在渲染組件時(shí),從開(kāi)始到渲染完成整個(gè)過(guò)程是一氣呵成的,無(wú)法中斷

如果組件較大,那么js線程會(huì)一直執(zhí)行,然后等到整棵VDOM樹(shù)計(jì)算完成后,才會(huì)交給渲染的線程

這就會(huì)導(dǎo)致一些用戶交互、動(dòng)畫(huà)等任務(wù)無(wú)法立即得到處理,導(dǎo)致卡頓的情況

二、是什么

React Fiber 是 Facebook 花費(fèi)兩年余時(shí)間對(duì) React 做出的一個(gè)重大改變與優(yōu)化,是對(duì) React 核心算法的一次重新實(shí)現(xiàn)。從Facebook在 React Conf 2017 會(huì)議上確認(rèn),React Fiber 在React 16 版本發(fā)布

在react中,主要做了以下的操作:

  • 為每個(gè)增加了優(yōu)先級(jí),優(yōu)先級(jí)高的任務(wù)可以中斷低優(yōu)先級(jí)的任務(wù)。然后再重新,注意是重新執(zhí)行優(yōu)先級(jí)低的任務(wù)
  • 增加了異步任務(wù),調(diào)用requestIdleCallback api,瀏覽器空閑的時(shí)候執(zhí)行
  • dom diff樹(shù)變成了鏈表,一個(gè)dom對(duì)應(yīng)兩個(gè)fiber(一個(gè)鏈表),對(duì)應(yīng)兩個(gè)隊(duì)列,這都是為找到被中斷的任務(wù),重新執(zhí)行

從架構(gòu)角度來(lái)看,F(xiàn)iber 是對(duì) React核心算法(即調(diào)和過(guò)程)的重寫(xiě)

從編碼角度來(lái)看,F(xiàn)iber是 React內(nèi)部所定義的一種數(shù)據(jù)結(jié)構(gòu),它是 Fiber樹(shù)結(jié)構(gòu)的節(jié)點(diǎn)單位,也就是 React 16 新架構(gòu)下的虛擬DOM

一個(gè) fiber就是一個(gè) JavaScript對(duì)象,包含了元素的信息、該元素的更新操作隊(duì)列、類(lèi)型,其數(shù)據(jù)結(jié)構(gòu)如下:

 
 
 
 
  1. type Fiber = { 
  2.   // 用于標(biāo)記fiber的WorkTag類(lèi)型,主要表示當(dāng)前fiber代表的組件類(lèi)型如FunctionComponent、ClassComponent等 
  3.   tag: WorkTag, 
  4.   // ReactElement里面的key 
  5.   key: null | string, 
  6.   // ReactElement.type,調(diào)用`createElement`的第一個(gè)參數(shù) 
  7.   elementType: any, 
  8.   // The resolved function/class/ associated with this fiber. 
  9.   // 表示當(dāng)前代表的節(jié)點(diǎn)類(lèi)型 
  10.   type: any, 
  11.   // 表示當(dāng)前FiberNode對(duì)應(yīng)的element組件實(shí)例 
  12.   stateNode: any, 
  13.  
  14.   // 指向他在Fiber節(jié)點(diǎn)樹(shù)中的`parent`,用來(lái)在處理完這個(gè)節(jié)點(diǎn)之后向上返回 
  15.   return: Fiber | null, 
  16.   // 指向自己的第一個(gè)子節(jié)點(diǎn) 
  17.   child: Fiber | null, 
  18.   // 指向自己的兄弟結(jié)構(gòu),兄弟節(jié)點(diǎn)的return指向同一個(gè)父節(jié)點(diǎn) 
  19.   sibling: Fiber | null, 
  20.   index: number, 
  21.  
  22.   ref: null | (((handle: mixed) => void) & { _stringRef: ?string }) | RefObject, 
  23.  
  24.   // 當(dāng)前處理過(guò)程中的組件props對(duì)象 
  25.   pendingProps: any, 
  26.   // 上一次渲染完成之后的props 
  27.   memoizedProps: any, 
  28.  
  29.   // 該Fiber對(duì)應(yīng)的組件產(chǎn)生的Update會(huì)存放在這個(gè)隊(duì)列里面 
  30.   updateQueue: UpdateQueue | null, 
  31.  
  32.   // 上一次渲染的時(shí)候的state 
  33.   memoizedState: any, 
  34.  
  35.   // 一個(gè)列表,存放這個(gè)Fiber依賴的context 
  36.   firstContextDependency: ContextDependency | null, 
  37.  
  38.   mode: TypeOfMode, 
  39.  
  40.   // Effect 
  41.   // 用來(lái)記錄Side Effect 
  42.   effectTag: SideEffectTag, 
  43.  
  44.   // 單鏈表用來(lái)快速查找下一個(gè)side effect 
  45.   nextEffect: Fiber | null, 
  46.  
  47.   // 子樹(shù)中第一個(gè)side effect 
  48.   firstEffect: Fiber | null, 
  49.   // 子樹(shù)中最后一個(gè)side effect 
  50.   lastEffect: Fiber | null, 
  51.  
  52.   // 代表任務(wù)在未來(lái)的哪個(gè)時(shí)間點(diǎn)應(yīng)該被完成,之后版本改名為 lanes 
  53.   expirationTime: ExpirationTime, 
  54.  
  55.   // 快速確定子樹(shù)中是否有不在等待的變化 
  56.   childExpirationTime: ExpirationTime, 
  57.  
  58.   // fiber的版本池,即記錄fiber更新過(guò)程,便于恢復(fù) 
  59.   alternate: Fiber | null, 

三、如何解決

Fiber把渲染更新過(guò)程拆分成多個(gè)子任務(wù),每次只做一小部分,做完看是否還有剩余時(shí)間,如果有繼續(xù)下一個(gè)任務(wù);如果沒(méi)有,掛起當(dāng)前任務(wù),將時(shí)間控制權(quán)交給主線程,等主線程不忙的時(shí)候在繼續(xù)執(zhí)行

即可以中斷與恢復(fù),恢復(fù)后也可以復(fù)用之前的中間狀態(tài),并給不同的任務(wù)賦予不同的優(yōu)先級(jí),其中每個(gè)任務(wù)更新單元為 React Element 對(duì)應(yīng)的 Fiber節(jié)點(diǎn)

實(shí)現(xiàn)的上述方式的是requestIdleCallback方法

window.requestIdleCallback()方法將在瀏覽器的空閑時(shí)段內(nèi)調(diào)用的函數(shù)排隊(duì)。這使開(kāi)發(fā)者能夠在主事件循環(huán)上執(zhí)行后臺(tái)和低優(yōu)先級(jí)工作,而不會(huì)影響延遲關(guān)鍵事件,如動(dòng)畫(huà)和輸入響應(yīng)

首先 React 中任務(wù)切割為多個(gè)步驟,分批完成。在完成一部分任務(wù)之后,將控制權(quán)交回給瀏覽器,讓瀏覽器有時(shí)間再進(jìn)行頁(yè)面的渲染。等瀏覽器忙完之后有剩余時(shí)間,再繼續(xù)之前 React 未完成的任務(wù),是一種合作式調(diào)度。

該實(shí)現(xiàn)過(guò)程是基于 Fiber節(jié)點(diǎn)實(shí)現(xiàn),作為靜態(tài)的數(shù)據(jù)結(jié)構(gòu)來(lái)說(shuō),每個(gè) Fiber 節(jié)點(diǎn)對(duì)應(yīng)一個(gè) React element,保存了該組件的類(lèi)型(函數(shù)組件/類(lèi)組件/原生組件等等)、對(duì)應(yīng)的 DOM 節(jié)點(diǎn)等信息。

作為動(dòng)態(tài)的工作單元來(lái)說(shuō),每個(gè) Fiber 節(jié)點(diǎn)保存了本次更新中該組件改變的狀態(tài)、要執(zhí)行的工作。

每個(gè) Fiber 節(jié)點(diǎn)有個(gè)對(duì)應(yīng)的 React element,多個(gè) Fiber節(jié)點(diǎn)根據(jù)如下三個(gè)屬性構(gòu)建一顆樹(shù):

 
 
 
 
  1. // 指向父級(jí)Fiber節(jié)點(diǎn) 
  2. this.return = null 
  3. // 指向子Fiber節(jié)點(diǎn) 
  4. this.child = null 
  5. // 指向右邊第一個(gè)兄弟Fiber節(jié)點(diǎn) 
  6. this.sibling = null 

通過(guò)這些屬性就能找到下一個(gè)執(zhí)行目標(biāo)

參考文獻(xiàn)

https://juejin.cn/post/6926432527980691470

https://zhuanlan.zhihu.com/p/137234573

https://vue3js.cn/interview


文章名稱:面試官:說(shuō)說(shuō)對(duì)React Fiber架構(gòu)的理解?解決了什么問(wèn)題?
網(wǎng)頁(yè)URL:http://www.5511xx.com/article/dheeoog.html