最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解React調(diào)度(Scheduler)原理

 更新時(shí)間:2022年07月04日 09:01:20   作者:YuLong~W  
本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

異步調(diào)度

問(wèn)題:由于對(duì)于大型的 React 應(yīng)用,會(huì)存在一次更新,遞歸遍歷大量的虛擬 DOM ,造成占用 js 線程,使得瀏覽器沒(méi)有時(shí)間去做一些動(dòng)畫(huà)效果,伴隨項(xiàng)目越來(lái)越大,項(xiàng)目會(huì)越來(lái)越卡。

對(duì)比Vue:

Vue 有這 template 模版收集依賴的過(guò)程,輕松構(gòu)建響應(yīng)式,使得在一次更新中,Vue 能夠迅速響應(yīng),找到需要更新的范圍,然后以組件粒度更新組件,渲染視圖。

React 中,一次更新 React 無(wú)法知道此次更新的波及范圍,所以 React 選擇從根節(jié)點(diǎn)開(kāi)始 diff ,查找不同,更新這些不同。

解決:

把 React 的更新,交給瀏覽器自己控制,瀏覽器先執(zhí)行繪制任務(wù),空閑時(shí)間執(zhí)行更新任務(wù),解決了卡頓問(wèn)題。即采用異步調(diào)度的方法。

時(shí)間分片

React讓瀏覽器控制React更新:瀏覽器每執(zhí)行一次事件循環(huán)都會(huì):處理事件,執(zhí)行 js,調(diào)用requestAnimation,布局 Layout,繪制 Paint,在一次執(zhí)行后,瀏覽器進(jìn)入空閑時(shí),可以執(zhí)行更新任務(wù)

谷歌瀏覽器提供的一個(gè) API, 在瀏覽器有空余的時(shí)間,瀏覽器就會(huì)調(diào)用 requestIdleCallback 的回調(diào)。

requestIdleCallback(callback,{ timeout })

  • callback 回調(diào)。瀏覽器空余時(shí)間執(zhí)行回調(diào)函數(shù)。
  • timeout 超時(shí)時(shí)間。如果瀏覽器長(zhǎng)時(shí)間沒(méi)有空閑,那么回調(diào)就不會(huì)執(zhí)行,為了解決這個(gè)問(wèn)題,可以通過(guò) requestIdleCallback 的第二個(gè)參數(shù)指定一個(gè)超時(shí)時(shí)間。

React 為了防止 requestIdleCallback 中的任務(wù)由于瀏覽器沒(méi)有空閑時(shí)間而卡死,所以設(shè)置了 5 個(gè)優(yōu)先級(jí)。

  • Immediate -1 需要立刻執(zhí)行。
  • UserBlocking 250ms 超時(shí)時(shí)間250ms,一般指的是用戶交互。
  • Normal 5000ms 超時(shí)時(shí)間5s,不需要直觀立即變化的任務(wù),比如網(wǎng)絡(luò)請(qǐng)求。
  • Low 10000ms 超時(shí)時(shí)間10s,肯定要執(zhí)行的任務(wù),但是可以放在最后處理。
  • Idle 一些沒(méi)有必要的任務(wù),可能不會(huì)執(zhí)行。

模擬requestdleCallback

條件:

  • 可以主動(dòng)讓出主線程,讓瀏覽器去渲染視圖。
  • 一次事件循環(huán)只執(zhí)行一次,因?yàn)閳?zhí)行一個(gè)以后,還會(huì)請(qǐng)求下一次的時(shí)間片。

宏任務(wù):在下次事件循環(huán)中執(zhí)行,不會(huì)阻塞瀏覽器更新。且瀏覽器一次只會(huì)執(zhí)行一個(gè)宏任務(wù)。

1、采用setTimeout(fn, 0),間隔時(shí)間會(huì)變成 4 毫秒左右,不是最優(yōu)選方案

2、采用MessageChannel 接口,允許開(kāi)發(fā)者創(chuàng)建一個(gè)新的消息通道,并通過(guò)它的兩個(gè) MessagePort 屬性發(fā)送數(shù)據(jù)。

在一次更新中,向?yàn)g覽器請(qǐng)求執(zhí)行更新任務(wù),調(diào)用 requesetHostCallbcak,將更新任務(wù) 函數(shù)callback賦值給 scheduleHostCallback,port2 向 port1 發(fā)起 postMessage消息通知。

port1 會(huì)通過(guò) onmessage,接受來(lái)自 port2 消息,執(zhí)行更新任務(wù) scheduleHostCallback,執(zhí)行完后,清空任務(wù)。

異步調(diào)度原理

React 發(fā)生一次更新,會(huì)統(tǒng)一走 ensureRootIsScheduled(調(diào)度應(yīng)用)

對(duì)于 正常更新 會(huì)走 performSyncWorkOnRoot 邏輯,最后會(huì)走 workLoopSync 。

對(duì)于 低優(yōu)先級(jí)的異步更新 會(huì)走 performConcurrentWorkOnRoot 邏輯,最后會(huì)走 workLoopConcurrent

區(qū)別:異步模式會(huì)調(diào)用一個(gè) shouldYield(),如果當(dāng)前瀏覽器沒(méi)有空余時(shí)間, shouldYield 會(huì)中止循環(huán),直到瀏覽器有空閑時(shí)間后再繼續(xù)遍歷,從而達(dá)到終止渲染的目的。解決了一次性遍歷大量的 fiber ,導(dǎo)致瀏覽器沒(méi)有時(shí)間執(zhí)行一些渲染任務(wù),導(dǎo)致了頁(yè)面卡頓。

1、scheduleCallback

更新任務(wù)、異步更新任務(wù)都是由調(diào)度器 scheduleCallback 統(tǒng)一調(diào)度的

正常更新任務(wù):

scheduleCallback(Immediate,workLoopSync)

異步更新任務(wù):

/* 計(jì)算超時(shí)等級(jí),就是如上那五個(gè)等級(jí) */
var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
scheduleCallback(priorityLevel,workLoopConcurrent)

scheduleCallback() 函數(shù)執(zhí)行過(guò)程

scheduleCallback 流程如下:

  • 創(chuàng)建一個(gè)新的任務(wù) newTask。
  • 通過(guò)任務(wù)的開(kāi)始時(shí)間( startTime ) 和 當(dāng)前時(shí)間( currentTime ) 比較:當(dāng) startTime > currentTime, 說(shuō)明未過(guò)期,存到 timerQueue,當(dāng) startTime <= currentTime,說(shuō)明已過(guò)期, 存到 taskQueue。
  • 如果任務(wù)沒(méi)有過(guò)期,用 requestHostTimeout 延時(shí)執(zhí)行 handleTimeout
  • 如果任務(wù)過(guò)期,并且沒(méi)有調(diào)度中的任務(wù),那么調(diào)度 requestHostCallback
  • 本質(zhì)上調(diào)度的是 flushWork。

2、requestHostTimeout

通過(guò) setTimeout 來(lái)進(jìn)行延時(shí)指定時(shí)間的。

延時(shí)執(zhí)行 handleTimeout,cancelHostTimeout 用于清除當(dāng)前的延時(shí)器。

3、handleTimeout

延時(shí)時(shí)間后,handleTimeout 會(huì)把任務(wù)重新放在 requestHostCallback 調(diào)度。

通過(guò) advanceTimers 將 timerQueue 中過(guò)期的任務(wù)轉(zhuǎn)移到 taskQueue 中。然后調(diào)用 requestHostCallback 調(diào)度過(guò)期的任務(wù)。

4、advanceTimers

如果任務(wù)已經(jīng)過(guò)期,那么將 timerQueue 中的過(guò)期任務(wù),放入 taskQueue。

5、flushWork

requestHostCallback ,放入 MessageChannel 中的回調(diào)函數(shù)是flushWork。

flushWork 如果有延時(shí)任務(wù)執(zhí)行的話,那么會(huì)先暫停延時(shí)任務(wù),然后調(diào)用 workLoop ,去真正執(zhí)行超時(shí)的更新任務(wù)。

6、workLoop

workLoop 是調(diào)度中的 workLoop

React 的更新任務(wù)最后都是放在 taskQueue 中

workLoop 會(huì)依次更新過(guò)期任務(wù)隊(duì)列中的任務(wù)

調(diào)度流程圖

總結(jié)

1、異步調(diào)度原因

2、時(shí)間分片和 requestIdleCallback

3、異步調(diào)度原理

4、調(diào)度流程

到此這篇關(guān)于深入理解React 調(diào)度(Scheduler)原理的文章就介紹到這了,更多相關(guān)React 調(diào)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • ReactJs設(shè)置css樣式的方法

    ReactJs設(shè)置css樣式的方法

    本篇文章主要介紹了ReactJs設(shè)置css樣式的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • React簡(jiǎn)便獲取經(jīng)緯度信息的方法詳解

    React簡(jiǎn)便獲取經(jīng)緯度信息的方法詳解

    在現(xiàn)代的Web應(yīng)用程序中,獲取用戶的地理位置信息是一項(xiàng)常見(jiàn)的需求,本文我們將介紹如何在React應(yīng)用程序中簡(jiǎn)便地獲取用戶的經(jīng)緯度信息,需要的可以參考下
    2023-11-11
  • React彈窗使用方式NiceModal重新思考

    React彈窗使用方式NiceModal重新思考

    這篇文章主要為大家介紹了React彈窗使用方式NiceModal重新思考分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • React合成事件原理及實(shí)現(xiàn)(React18和React16)

    React合成事件原理及實(shí)現(xiàn)(React18和React16)

    本文主要介紹了React合成事件原理及實(shí)現(xiàn),包含React18和React16兩種版本,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • React tsx生成隨機(jī)驗(yàn)證碼

    React tsx生成隨機(jī)驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了React tsx生成隨機(jī)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    使用VScode 插件debugger for chrome 調(diào)試react源碼的方法

    這篇文章主要介紹了使用VScode 插件debugger for chrome 調(diào)試react源碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • React中useCallback useMemo到底該怎么用

    React中useCallback useMemo到底該怎么用

    在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時(shí),默認(rèn)情況下整個(gè)組件都會(huì)重新渲染。換句話說(shuō),如果組件中的任何值更新,整個(gè)組件將重新渲染,包括沒(méi)有更改values/props的函數(shù)/組件。在react中,我們可以通過(guò)memo,useMemo以及useCallback來(lái)防止子組件的rerender
    2023-02-02
  • react native環(huán)境安裝流程

    react native環(huán)境安裝流程

    React Native 是目前流行的跨平臺(tái)移動(dòng)應(yīng)用開(kāi)發(fā)框架之一。本文介紹react native環(huán)境安裝流程及遇到問(wèn)題解決方法,感興趣的朋友一起看看吧
    2021-05-05
  • React-Native做一個(gè)文本輸入框組件的實(shí)現(xiàn)代碼

    React-Native做一個(gè)文本輸入框組件的實(shí)現(xiàn)代碼

    這篇文章主要介紹了React-Native做一個(gè)文本輸入框組件的實(shí)現(xiàn)代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-08-08
  • React函數(shù)組件與類的區(qū)別有哪些

    React函數(shù)組件與類的區(qū)別有哪些

    函數(shù)式組件的基本意義就是,組件實(shí)際上是一個(gè)函數(shù),不是類,下面這篇文章主要給大家介紹了關(guān)于React中函數(shù)組件與類的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10

最新評(píng)論

通榆县| 晋宁县| 沛县| 湖南省| 平和县| 醴陵市| 平度市| 郯城县| 姚安县| 富顺县| 遂平县| 东乌珠穆沁旗| 广西| 文成县| 中超| 甘德县| 长寿区| 保康县| 冷水江市| 小金县| 镇赉县| 沙坪坝区| 常州市| 工布江达县| 岳普湖县| 五峰| 嘉祥县| 大余县| 汉中市| 潮州市| 嘉鱼县| 白水县| 儋州市| 清河县| 罗源县| 张北县| 祁门县| 清苑县| 宁安市| 昌邑市| 和平县|