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

React不使用requestIdleCallback實(shí)現(xiàn)調(diào)度原理解析

 更新時(shí)間:2022年11月28日 11:02:08   作者:用戶(hù)6816925221619  
這篇文章主要為大家介紹了React不使用requestIdleCallback實(shí)現(xiàn)調(diào)度原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.起因

最近在一邊啃源碼,一邊手寫(xiě)fiber嘛,然后也看了很多博客和資料,基本上大伙好像都是說(shuō)用requestIdleCallback來(lái)模擬react實(shí)現(xiàn)一個(gè)空閑時(shí)間調(diào)度。但我自己手寫(xiě)的時(shí)候把怎么用怎么怪,老是感覺(jué)有什么地方不對(duì)勁而且是在調(diào)度過(guò)程中,可能是因?yàn)槲沂窍雽?xiě)出來(lái)來(lái)一個(gè)相對(duì)健全一點(diǎn)的模版方便我以后寫(xiě)源碼的其他部分把,然后分析了一下所以有了這篇博客。

2.查找問(wèn)題

1.requestIdleCallback是利用幀之間空閑時(shí)間來(lái)執(zhí)行JS,它是一個(gè)低優(yōu)先級(jí)的處理策略它給我的感覺(jué)就是做一些類(lèi)似上報(bào)之類(lèi)的操作,但實(shí)際上Fiber的構(gòu)建以及渲染內(nèi)容,并不算是一個(gè)低優(yōu)先級(jí)任務(wù)。

2.兼容性這個(gè)就總所周知了,這個(gè)api并不適合在生產(chǎn)環(huán)境上。

3.requestIdleCallback實(shí)際上是在布局和繪制之后,那意味在也許你在里面做的事情(可能是通過(guò)數(shù)據(jù)修改觸發(fā)dom修改)會(huì)重排。可以看看這個(gè)試驗(yàn)

3.解決問(wèn)題

所以這時(shí)候我們就可以回到源碼中去看,react是怎么實(shí)現(xiàn)的,源碼地址。

核心調(diào)度實(shí)現(xiàn)

    // 有執(zhí)行任務(wù)
    if (scheduledHostCallback !== null) {
      const currentTime = getCurrentTime();
      // 計(jì)算一幀的過(guò)期時(shí)間點(diǎn)
      deadline = currentTime + yieldInterval;
      const hasTimeRemaining = true;
      try {
        // 執(zhí)行c回調(diào)
        const hasMoreWork = scheduledHostCallback(
          hasTimeRemaining,
          currentTime,
        );
        // 執(zhí)行完該回調(diào)后, 判斷后續(xù)是否還有其他任務(wù)
        if (!hasMoreWork) {
          isMessageLoopRunning = false;
          scheduledHostCallback = null;
        } else {
          // 還有其他任務(wù), 推進(jìn)進(jìn)入下一個(gè)宏任務(wù)隊(duì)列中
          port.postMessage(null);
        }
      } catch (error) {
        // If a scheduler task throws, exit the current browser task so the
        // error can be observed.
        port.postMessage(null);
        throw error;
      }
    } else {
      isMessageLoopRunning = false;
    }
    // Yielding to the browser will give it a chance to paint, so we can
    // reset this.
    // 重置狀態(tài)
    needsPaint = false;
  };

  const channel = new MessageChannel();
  // port2 發(fā)送
  const port = channel.port2;
  // port1 接收
  channel.port1.onmessage = performWorkUntilDeadline;
  // 在每一幀中執(zhí)行任務(wù)
  requestHostCallback = function(callback) {
    // 回調(diào)注冊(cè)
    scheduledHostCallback = callback;
    if (!isMessageLoopRunning) {
      isMessageLoopRunning = true;
      // 進(jìn)入宏任務(wù)隊(duì)列
      port.postMessage(null);
    }
  };
  // 取消回調(diào)
  cancelHostCallback = function() {
    scheduledHostCallback = null;
  };
  // 設(shè)置超時(shí)回調(diào)
  requestHostTimeout = function(callback, ms) {
    taskTimeoutID = setTimeout(() => {
      callback(getCurrentTime());
    }, ms);
  };
  // 取消超時(shí)
  cancelHostTimeout = function() {
    clearTimeout(taskTimeoutID);
    taskTimeoutID = -1;
  };

代碼里的注釋寫(xiě)得很清楚了把,但有幾個(gè)點(diǎn)可以說(shuō)一下。

1.首先選擇宏任務(wù),因?yàn)槲覀冃枰ゼ皶r(shí)的讓出主線程(微任務(wù)并不會(huì)讓出主線程也是在更新頁(yè)面前去執(zhí)行)。

2.其次是宏任務(wù)中的選擇,MessageChannel,setTimeout,requestAnimationFrame,都是宏任務(wù),setTimeout會(huì)浪費(fèi)4ms(這個(gè)大伙可以去看看),requestAnimationFrame的觸發(fā)時(shí)間是不穩(wěn)定的(可以看看瀏覽器的更新頁(yè)面機(jī)制),所以我猜想最后就選了MessageChannel把。

4.總結(jié)

其實(shí)到這思路也比較明了了,把React中為什么不使用requestIdleCallback理清楚,還順便把React的核心調(diào)度原理看了一下。

5.吐槽

唉,其實(shí)看源碼和手寫(xiě)源碼完全是兩種感覺(jué),更多的是體現(xiàn)在實(shí)現(xiàn)細(xì)節(jié)和代碼耦合性健壯性的問(wèn)題,寫(xiě)是怎么寫(xiě)都行,但如何寫(xiě)優(yōu)雅的方便人迭代的代碼就好燒腦。比如你就想實(shí)現(xiàn)一個(gè)fiber的大體思路就不難,但是如果想你在fiber上加hook,難度幾何飆升,基礎(chǔ)構(gòu)建和細(xì)節(jié)實(shí)現(xiàn)就很重要了,手寫(xiě)肯定是不等于抄,還需要在里面加寫(xiě)自己的想法和如何簡(jiǎn)化的方案。

以上就是React不使用requestIdleCallback實(shí)現(xiàn)調(diào)度原理解析的詳細(xì)內(nèi)容,更多關(guān)于React不使用requestIdleCallback調(diào)度的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • ReactRouter的實(shí)現(xiàn)方法

    ReactRouter的實(shí)現(xiàn)方法

    這篇文章主要介紹了ReactRouter的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • React教程之封裝一個(gè)Portal可復(fù)用組件的方法

    React教程之封裝一個(gè)Portal可復(fù)用組件的方法

    react的核心之一是組件,下面這篇文章主要給大家介紹了關(guān)于React教程之封裝一個(gè)Portal可復(fù)用組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • React中的JSX??{?}的使用詳解

    React中的JSX??{?}的使用詳解

    這篇文章主要介紹了React中的JSX{?}的使用,React使用JSX來(lái)替代常規(guī)的JavaScript,JSX可以理解為的JavaScript語(yǔ)法擴(kuò)展,它里面的標(biāo)簽申明要符合XML規(guī)范要求,對(duì)React?JSX使用感興趣的朋友一起看看吧
    2022-08-08
  • 深入理解react-router@4.0 使用和源碼解析

    深入理解react-router@4.0 使用和源碼解析

    這篇文章主要介紹了深入理解react-router@4.0 使用和源碼解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 詳解如何在react中搭建d3力導(dǎo)向圖

    詳解如何在react中搭建d3力導(dǎo)向圖

    本篇文章主要介紹了如何在react中搭建d3力導(dǎo)向圖,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • React Hook 監(jiān)聽(tīng)localStorage更新問(wèn)題

    React Hook 監(jiān)聽(tīng)localStorage更新問(wèn)題

    這篇文章主要介紹了React Hook 監(jiān)聽(tīng)localStorage更新問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 使用react-native-doc-viewer實(shí)現(xiàn)文檔預(yù)覽

    使用react-native-doc-viewer實(shí)現(xiàn)文檔預(yù)覽

    這篇文章主要介紹了使用react-native-doc-viewer實(shí)現(xiàn)文檔預(yù)覽,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • React中傳遞組件的三種方式小結(jié)

    React中傳遞組件的三種方式小結(jié)

    通過(guò)傳遞組件,我們可以將復(fù)雜組件內(nèi)部的一部分 UI 交由外部組件來(lái)控制渲染,這也是控制反轉(zhuǎn)(Inversion of Control)的一種體現(xiàn),在 React 中,我們可以通過(guò)三種方式來(lái)傳遞組件,本文就來(lái)給大家述說(shuō)這三種方式,需要的朋友可以參考下
    2023-07-07
  • 詳解React項(xiàng)目的服務(wù)端渲染改造(koa2+webpack3.11)

    詳解React項(xiàng)目的服務(wù)端渲染改造(koa2+webpack3.11)

    本篇文章主要介紹了詳解React項(xiàng)目的服務(wù)端渲染改造(koa2+webpack3.11),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • react-draggable實(shí)現(xiàn)拖拽功能實(shí)例詳解

    react-draggable實(shí)現(xiàn)拖拽功能實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于react-draggable實(shí)現(xiàn)拖拽功能的相關(guān)資料,React-Draggable一個(gè)使元素可拖動(dòng)的簡(jiǎn)單組件,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08

最新評(píng)論

和田县| 江西省| 邹平县| 徐州市| 佳木斯市| 河南省| 冷水江市| 宜都市| 二连浩特市| 奉化市| 东方市| 托克逊县| 宝坻区| 邮箱| 通江县| 北川| 固阳县| 昭苏县| 溆浦县| 酉阳| 冕宁县| 海口市| 普兰店市| 太原市| 中超| 玛沁县| 瑞安市| 留坝县| 思茅市| 静乐县| 全椒县| 若羌县| 连平县| 芷江| 灌南县| 隆昌县| 阜宁县| 分宜县| 大厂| 和龙市| 杭州市|