postTask:React 的殺手鐧被瀏覽器原生實現了?

React這幾年一直在完善的**「併發模式」**主要由以下兩部分組成:

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

如果現在告訴你,React嘔心瀝血多年實現的**「優先級調度」**,瀏覽器原生就支持,會不會很驚訝?

文章參考 Building a Faster Web Experience with the postTask Scheduler[1]。

什麼是優先級調度

假設,我們有個**「記錄日誌」**的腳本需要在頁面初始化後執行:

initCriticalTracking();

調用棧火炬圖如下:

可以看到,這是個執行了 249.08ms 的長任務,在執行期間瀏覽器會掉幀(表現爲:瀏覽器卡頓)。

現在,我們將其包裹在**「優先級調度函數 scheduler.postTask」**的回調函數中:

scheduler.postTask(() => initCriticalTracking());

長任務被分解爲多個短任務:

在每個任務之間瀏覽器有機會重排、重繪,減少了掉幀的可能性。

這種**「根據任務優先級將任務拆解,分配執行時間的技術」**,就是**「優先級調度」**。

scheduler.postTask[2] 是Chrome實現的**「優先級調度 API」**。

scheduler.postTask 屬於試驗功能,需要在 chrome://flags 中打開 #enable-experimental-web-platform-features

之前是如何實現優先級調度的

scheduler.postTask出現之前,通常使用瀏覽器提供的**「會在不同階段調用的 API」**模擬**「優先級調度」**,比如:

React使用MessageChannel實現優先級調度,setTimeout作爲降級方案。

但是,這些API畢竟都有本職工作。用他們實現的**「優先級調度」**比較粗糙。

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

postTask Scheduler 的使用

scheduler.postTask有 3 種可選優先級:

使用方式很簡單,通過以下方式註冊的回調函數會以**「默認優先級」**調度:

// 默認優先級
scheduler.postTask(() => console.log('Hello, postTask'));

你也可以指定優先級與執行延遲:

// 調用後延遲1秒執行,優先級最低
scheduler.postTask(() => console.log('Hello, postTask'){
   delay: 1000,
   priority: 'background',
});

postTask建立在 AbortSignal API[3] 上,所以我們可以取消尚在排隊還未執行的回調函數。

通過使用TaskController API控制:

const controller = new TaskController('background');
window.addEventListener('beforeunload'() => controller.abort());
 
scheduler.postTask(() => console.log('Hello, postTask'){
   signal: controller.signal,
});

同時,實驗性的schedule.wait方法可以讓我們輕鬆的等待某一時機後再執行任務。

比如,我們可以在頁面加載完成後異步加載xxx.js

async function loadxxx() {
  // 等待事件被派發
  await scheduler.wait('myPageHasLoaded');
  return import('xxx.js');
}
 
// 頁面加載後派發事件
window.dispatchEvent(new CustomEvent('myPageHasLoaded'));

以上代碼被簡化爲postTaskevent配置項:

scheduler.postTask(() => import('xxx.js'){
   event: 'myPageHasLoaded'
})

總結

**「優先級調度」**可以應用在很多領域,比如:

......

可以預見,未來這勢必會增加前端編程複雜度。

就像曾經,當web應用複雜到一定程度時,出現了前端框架,開發者不用直接操作DOM

未來,當**「優先級調度」**複雜到一定程度時,一定也會出現集成解決方案,讓開發者不用直接操作優先級

慢着,這不就是React現在在做的事麼?

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZW4kwSYelnuUA0grKQmXow