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

資訊專欄INFORMATION COLUMN

React 重要的一次重構(gòu):認(rèn)識(shí)異步渲染架構(gòu) Fiber

cppowboy / 3526人閱讀

摘要:在之前的叫,是新的,這次更新到架構(gòu)是一次重量級(jí)的核心架構(gòu)的替換,為了完成這次替換已經(jīng)準(zhǔn)備了兩三年的時(shí)間了。因此團(tuán)隊(duì)引入了異步渲染這個(gè)概念,而采用架構(gòu)可以實(shí)現(xiàn)這種異步渲染的方式。官方目前已經(jīng)把和標(biāo)記為,并使用新的生命周期函數(shù)和進(jìn)行替換。

Diff 算法

熟悉 react 的朋友都知道,在 react 中有個(gè)核心的算法,叫 diff 算法。web 界面由 dom 樹(shù)組成,不同的 dom 樹(shù)會(huì)渲染出不同的界面。react 使用 virtual dom 來(lái)表示 dom 樹(shù),而 diff 算法就是用于比較 virtual dom 樹(shù)的區(qū)別,并更新界面需要更新的部分。diff 算法和 virtual dom 的完美結(jié)合的過(guò)程被稱為 reconciler,這可是 react 攻城拔寨的絕對(duì)利器。有了 reconciler,開(kāi)發(fā)者可以脫身操作真實(shí)的 dom 樹(shù),只需要向 react 描述界面的狀態(tài),而 react 會(huì)幫助你高效的完成真正 dom 操作。

在 react16 之前的 reconciler 叫 stack reconciler,fiber 是 react 新的 reconciler,這次更新到 fiber 架構(gòu)是一次重量級(jí)的核心架構(gòu)的替換,react 為了完成這次替換已經(jīng)準(zhǔn)備了兩三年的時(shí)間了。

那么 fiber 究竟有什么好的呢?

Fiber 為何出現(xiàn)

不知道大家有沒(méi)有遇到過(guò)這樣的情況,點(diǎn)擊一個(gè)頁(yè)面的按鈕時(shí)感覺(jué)到頁(yè)面沒(méi)有任何的反應(yīng),讓你懷疑電腦是不是死機(jī)了,然后你快速切出瀏覽器,發(fā)現(xiàn)電腦并沒(méi)有死機(jī),于是再切回瀏覽器,這時(shí)候才發(fā)現(xiàn)頁(yè)面終于更新了。為什么會(huì)出現(xiàn)這種情況?在多數(shù)情況下,可能是因?yàn)闉g覽器忙著執(zhí)行相關(guān)的 js 代碼,導(dǎo)致瀏覽器主線程沒(méi)有及時(shí)響應(yīng)用戶的操作或者沒(méi)有及時(shí)更新界面。下面這張圖就表示了這種現(xiàn)象,你的公司只有一個(gè)程序員 (main thread),當(dāng)這個(gè)程序員在執(zhí)行你的任務(wù) (your code) 時(shí),處于沉浸式編程的狀態(tài),無(wú)法響應(yīng)外部的其他事件,什么下班吃飯,都是不存在的。這就像瀏覽器忙著執(zhí)行 js 代碼的時(shí)候,不會(huì)去執(zhí)行頁(yè)面更新等操作。

本著顧客是上帝的原則,作為一名優(yōu)秀的開(kāi)發(fā)者,怎么能夠允許出現(xiàn)這種情況降低用戶的體驗(yàn)?zāi)亍R虼?react 團(tuán)隊(duì)引入了異步渲染這個(gè)概念,而采用 fiber 架構(gòu)可以實(shí)現(xiàn)這種異步渲染的方式。

原先的 stack reconciler 像是一個(gè)遞歸執(zhí)行的函數(shù),從父組件調(diào)用子組件的 reconciler 過(guò)程就是一個(gè)遞歸執(zhí)行的過(guò)程,這也是為什么被稱為 stack reconciler 的原因。當(dāng)我們調(diào)用 setState 的時(shí)候,react 從根節(jié)點(diǎn)開(kāi)始遍歷,找出所有的不同,而對(duì)于特別龐大的 dom 樹(shù)來(lái)說(shuō),這個(gè)遞歸遍歷的過(guò)程會(huì)消耗特別長(zhǎng)的時(shí)間。在這個(gè)期間,任何交互和渲染都會(huì)被阻塞,這樣就給用戶一種“死機(jī)”的感覺(jué)。

fiber 的出現(xiàn)解決了這個(gè)問(wèn)題,它把 reconciler 的過(guò)程拆分成了一個(gè)個(gè)的小任務(wù),并在完成了小任務(wù)之后暫停執(zhí)行 js 代碼,然后檢查是否有需要更新的內(nèi)容和需要響應(yīng)的事件,做出相應(yīng)的處理后再繼續(xù)執(zhí)行 js 代碼。這樣就給了用戶一種應(yīng)用一直在運(yùn)行的感覺(jué),提高了用戶的體驗(yàn)。

Fiber 如何做到異步渲染

在做顯示方面的工作時(shí),經(jīng)常會(huì)聽(tīng)到一個(gè)目標(biāo)叫 60 幀,這表示的是畫(huà)面的更新頻率,也就是畫(huà)面每秒鐘更新 60 次。這是因?yàn)樵?60 幀的更新頻率下,頁(yè)面在人眼中顯得流暢,無(wú)明顯卡頓。每秒鐘更新 60 次也就是每 16ms 需要更新一次頁(yè)面,如果更新頁(yè)面消耗的時(shí)間不到 16ms,那么在下一次更新時(shí)機(jī)來(lái)到之前會(huì)剩下一點(diǎn)時(shí)間執(zhí)行其他的任務(wù),只要保證及時(shí)在 16ms 的間隔下更新界面就完全不會(huì)影響到頁(yè)面的流暢程度。fiber 的核心正是利用了 60 幀原則,實(shí)現(xiàn)了一個(gè)基于優(yōu)先級(jí)和 requestIdleCallback 的循環(huán)任務(wù)調(diào)度算法。

requestIdleCallback 是瀏覽器提供的一個(gè) api,可以讓瀏覽器在空閑的時(shí)候執(zhí)行回調(diào),在回調(diào)參數(shù)中可以獲取到當(dāng)前幀剩余的時(shí)間,fiber 利用了這個(gè)參數(shù),判斷當(dāng)前剩下的時(shí)間是否足夠繼續(xù)執(zhí)行任務(wù),如果足夠則繼續(xù)執(zhí)行,否則暫停任務(wù),并調(diào)用 requestIdleCallback 通知瀏覽器空閑的時(shí)候繼續(xù)執(zhí)行當(dāng)前的任務(wù)。

function fiber(剩余時(shí)間) {
 if (剩余時(shí)間 > 任務(wù)所需時(shí)間) {
 做任務(wù);
 } else {
 requestIdleCallback(fiber);
 }
}

fiber 還會(huì)為不同的任務(wù)設(shè)置不同的優(yōu)先級(jí),高優(yōu)先級(jí)任務(wù)是需要馬上展示到頁(yè)面上的,比如你正在輸入框中輸入文字,你肯定希望你的手指在鍵盤上敲下每一個(gè)按鍵時(shí),輸入框能立馬做出反饋,這樣你才能知道你的輸入是否正確,是否有效。低優(yōu)先級(jí)的任務(wù)則是像從服務(wù)器傳來(lái)了一些數(shù)據(jù),這個(gè)時(shí)候需要更新頁(yè)面,比如這篇文章喜歡的人數(shù)+1 或是評(píng)論+1,這并不是那么緊急的更新,延遲 100-200ms 并不會(huì)有多大差別,完全可以在后面進(jìn)行處理。fiber 會(huì)根據(jù)任務(wù)優(yōu)先級(jí)來(lái)動(dòng)態(tài)調(diào)整任務(wù)調(diào)度,優(yōu)先完成高優(yōu)先級(jí)的任務(wù)。

{ 
 Synchronous: 1, // 同步任務(wù),優(yōu)先級(jí)最高
 Task: 2, // 當(dāng)前調(diào)度正執(zhí)行的任務(wù)
 Animation 3, // 動(dòng)畫(huà)
 High: 4, // 高優(yōu)先級(jí)
 Low: 5, // 低優(yōu)先級(jí)
 Offscreen: 6, // 當(dāng)前屏幕外的更新,優(yōu)先級(jí)最低
}

在 fiber 架構(gòu)中,有一種數(shù)據(jù)結(jié)構(gòu),它的名字就叫做 fiber,這也是為什么新的 reconciler 叫做 fiber 的原因。fiber 其實(shí)就是一個(gè) js 對(duì)象,這個(gè)對(duì)象的屬性中比較重要的有 stateNodetag、return、child、siblingalternate。

Fiber = {
 tag // 標(biāo)記任務(wù)的進(jìn)度
 return // 父節(jié)點(diǎn)
 child // 子節(jié)點(diǎn)
 sibling // 兄弟節(jié)點(diǎn)
 alternate // 變化記錄
 .....
};

我們可以看出 fiber 基于鏈表結(jié)構(gòu),擁有一個(gè)個(gè)指針,指向它的父節(jié)點(diǎn)子節(jié)點(diǎn)和兄弟節(jié)點(diǎn),在 diff 的過(guò)程中,依照節(jié)點(diǎn)連接的關(guān)系進(jìn)行遍歷。

fiber 可能存在的問(wèn)題

在 fiber 中,更新是分階段的,具體分為兩個(gè)階段,首先是 reconciliation 的階段,這個(gè)階段在計(jì)算前后 dom 樹(shù)的差異,然后是 commit 的階段,這個(gè)階段將把更新渲染到頁(yè)面上。第一個(gè)階段是可以打斷的,因?yàn)檫@個(gè)階段耗時(shí)可能會(huì)很長(zhǎng),因此需要暫停下來(lái)去執(zhí)行其他更高優(yōu)先級(jí)的任務(wù),第二個(gè)階段則不會(huì)被打斷,會(huì)一口氣把更新渲染到頁(yè)面上。

由于 reconciliation 的階段會(huì)被打斷,可能會(huì)導(dǎo)致 commit 前的這些生命周期函數(shù)多次執(zhí)行。react 官方目前已經(jīng)把 componentWillMount、componentWillReceivePropscomponetWillUpdate 標(biāo)記為 unsafe,并使用新的生命周期函數(shù) getDerivedStateFromPropsgetSnapshotBeforeUpdate 進(jìn)行替換。

還有一個(gè)問(wèn)題是饑餓問(wèn)題,意思是如果高優(yōu)先級(jí)的任務(wù)一直插入,導(dǎo)致低優(yōu)先級(jí)的任務(wù)無(wú)法得到機(jī)會(huì)執(zhí)行,這被稱為饑餓問(wèn)題。對(duì)于這個(gè)問(wèn)題官方提出的解決方案是盡量復(fù)用已經(jīng)完成的操作來(lái)緩解。相信官方也正在努力提出更好的方法去解決這個(gè)問(wèn)題。

文 / Xss

編 / 熒聲

本文已由作者授權(quán)發(fā)布,版權(quán)屬于創(chuàng)宇前端。歡迎注明出處轉(zhuǎn)載本文。本文鏈接:https://knownsec-fed.com/2018...

想要訂閱更多來(lái)自知道創(chuàng)宇開(kāi)發(fā)一線的分享,請(qǐng)搜索關(guān)注我們的微信公眾號(hào):創(chuàng)宇前端(KnownsecFED)。歡迎留言討論,我們會(huì)盡可能回復(fù)。

感謝您的閱讀。

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

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

相關(guān)文章

  • 淺談React Fiber

    摘要:因?yàn)榘姹緦⒄嬲龔U棄這三生命周期到目前為止,的渲染機(jī)制遵循同步渲染首次渲染,更新時(shí)更新時(shí)卸載時(shí)期間每個(gè)周期函數(shù)各司其職,輸入輸出都是可預(yù)測(cè),一路下來(lái)很順暢。通過(guò)進(jìn)一步觀察可以發(fā)現(xiàn),預(yù)廢棄的三個(gè)生命周期函數(shù)都發(fā)生在虛擬的構(gòu)建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時(shí)間準(zhǔn)備前端招聘事項(xiàng)...

    izhuhaodev 評(píng)論0 收藏0
  • React 16」為 Luy 實(shí)現(xiàn) React Fiber 架構(gòu)

    摘要:開(kāi)始寫(xiě)代碼構(gòu)造函數(shù)講了那么多的理論,大家一定是暈了,但是沒(méi)辦法,架構(gòu)已經(jīng)比之前的簡(jiǎn)單要復(fù)雜太多了,因此不可能指望一次性把的內(nèi)容全部理解,需要反復(fù)多看。 前言 Facebook 的研發(fā)能力真是驚人, Fiber 架構(gòu)給 React 帶來(lái)了新視野的同時(shí),將調(diào)度一詞介紹給了前端,然而這個(gè)架構(gòu)實(shí)在不好懂,比起以前的 Vdom 樹(shù),新的 Fiber 樹(shù)就麻煩太多。 可以說(shuō),React 16 和 ...

    DevWiki 評(píng)論0 收藏0
  • React Fiber 架構(gòu)理解

    摘要:架構(gòu)理解引用原文是核心算法正在進(jìn)行的重新實(shí)現(xiàn)。構(gòu)建的過(guò)程就是的過(guò)程,通過(guò)來(lái)調(diào)度執(zhí)行一組任務(wù),每完成一個(gè)任務(wù)后回來(lái)看看有沒(méi)有插隊(duì)的更緊急的,把時(shí)間控制權(quán)交還給主線程,直到下一次回調(diào)再繼續(xù)構(gòu)建。 React Fiber 架構(gòu)理解 引用原文:React Fiber ArchitectureReact Fiber is an ongoing reimplementation of Reacts...

    Berwin 評(píng)論0 收藏0
  • Deep In React之淺談 React Fiber 架構(gòu)(一)

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

    Jiavan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<