<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          postTask:React的殺手锏被瀏覽器原生實現(xiàn)了?

          共 2616字,需瀏覽 6分鐘

           ·

          2021-10-09 19:26

          作者:卡頌
          來源:SegmentFault 思否社區(qū)


          大家好,我卡頌。

          React這幾年一直在完善的并發(fā)模式主要由以下兩部分組成:

          • 基于fiber實現(xiàn)的可中斷更新的架構(gòu)
          • 基于調(diào)度器的優(yōu)先級調(diào)度

          可以說,從16年開始重構(gòu)fiber架構(gòu)到今年底(或明年初)React18發(fā)布正式版,這期間React團隊大部分工作都是圍繞這兩點展開的。

          如果現(xiàn)在告訴你,React嘔心瀝血多年實現(xiàn)的優(yōu)先級調(diào)度,瀏覽器原生就支持,會不會很驚訝?


          文章參考Building a Faster Web Experience with the postTask Scheduler

          什么是優(yōu)先級調(diào)度

          假設(shè),我們有個記錄日志的腳本需要在頁面初始化后執(zhí)行:

          initCriticalTracking();

          調(diào)用棧火炬圖如下:



          可以看到,這是個執(zhí)行了249.08ms的長任務,在執(zhí)行期間瀏覽器會掉幀(表現(xiàn)為:瀏覽器卡頓)。
          現(xiàn)在,我們將其包裹在優(yōu)先級調(diào)度函數(shù)scheduler.postTask的回調(diào)函數(shù)中:
          scheduler.postTask(() => initCriticalTracking());
          長任務被分解為多個短任務:



          在每個任務之間瀏覽器有機會重排、重繪,減少了掉幀的可能性。
          這種根據(jù)任務優(yōu)先級將任務拆解,分配執(zhí)行時間的技術(shù),就是優(yōu)先級調(diào)度
          scheduler.postTaskChrome實現(xiàn)的優(yōu)先級調(diào)度API
          scheduler.postTask屬于試驗功能,需要在 chrome://flags 中打開 #enable-experimental-web-platform-features

          之前是如何實現(xiàn)優(yōu)先級調(diào)度的

          scheduler.postTask出現(xiàn)之前,通常使用瀏覽器提供的會在不同階段調(diào)用的API模擬優(yōu)先級調(diào)度,比如:
          • requestAnimationFrame(簡稱rAF)一般用來處理動畫,會在瀏覽器渲染前觸發(fā)

          • requestIdleCallback(簡稱rIC)在每一幀沒有其他任務的空閑時間調(diào)用

          • setTimeoutpostMessageMessageChannel在渲染之間觸發(fā)


          React使用MessageChannel實現(xiàn)優(yōu)先級調(diào)度,setTimeout作為降級方案。
          但是,這些API畢竟都有本職工作。用他們實現(xiàn)的優(yōu)先級調(diào)度比較粗糙。



          基于此原因,postTask Scheduler誕生了。

          postTask Scheduler的使用

          scheduler.postTask有3種可選優(yōu)先級:


          使用方式很簡單,通過以下方式注冊的回調(diào)函數(shù)會以默認優(yōu)先級調(diào)度:
          // 默認優(yōu)先級
          scheduler.postTask(() => console.log('Hello, postTask'));
          你也可以指定優(yōu)先級與執(zhí)行延遲:
          // 調(diào)用后延遲1秒執(zhí)行,優(yōu)先級最低
          scheduler.postTask(() => console.log('Hello, postTask'), {
             delay: 1000,
             priority: 'background',
          });
          postTask建立在AbortSignal API上,所以我們可以取消尚在排隊還未執(zhí)行的回調(diào)函數(shù)。
          通過使用TaskController API控制:
          const controller = new TaskController('background');
          window.addEventListener('beforeunload', () => controller.abort());
           
          scheduler.postTask(() => console.log('Hello, postTask'), {
             signal: controller.signal,
          });
          同時,實驗性的schedule.wait方法可以讓我們輕松的等待某一時機后再執(zhí)行任務。
          比如,我們可以在頁面加載完成后異步加載xxx.js
          async function loadxxx() {
            // 等待事件被派發(fā)
            await scheduler.wait('myPageHasLoaded');
            return import('xxx.js');
          }
           
          // 頁面加載后派發(fā)事件
          window.dispatchEvent(new CustomEvent('myPageHasLoaded'));
          以上代碼被簡化為postTaskevent配置項:
          scheduler.postTask(() => import('xxx.js'), {
             event: 'myPageHasLoaded'
          })

          總結(jié)

          優(yōu)先級調(diào)度可以應用在很多領(lǐng)域,比如:
          • 資源提前、延后請求
          • 第三方資源延遲加載
          ......
          可以預見,未來這勢必會增加前端編程復雜度。


          就像曾經(jīng),當web應用復雜到一定程度時,出現(xiàn)了前端框架,開發(fā)者不用直接操作DOM
          未來,當優(yōu)先級調(diào)度復雜到一定程度時,一定也會出現(xiàn)集成解決方案,讓開發(fā)者不用直接操作優(yōu)先級
          慢著,這不就是React現(xiàn)在在做的事么?


          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  WWW.撸一 | 欧美三级电影在线播放 | 男人的天堂久久 | 中文字幕人成人乱 | 亚洲sese图 |