requestIdleCallback在EventLoop的什麼階段執行?如何執行?

王铁柱6發表於2024-12-11

requestIdleCallback 在瀏覽器的事件迴圈(Event Loop)中,空閒階段(Idle Phase) 執行。 它會在瀏覽器完成其他高優先順序任務(例如處理使用者輸入、渲染頁面、執行 JavaScript 等)後,並且有剩餘時間時才會被呼叫。

執行方式:

  1. 註冊回撥函式: 使用 requestIdleCallback(callback, options) 註冊一個回撥函式 callbackoptions 可選,用於設定超時時間。

  2. 空閒階段呼叫: 瀏覽器在完成一個事件迴圈的 tasks、microtasks 佇列後,如果還有剩餘時間,就會進入空閒階段。這時,它會檢查是否有透過 requestIdleCallback 註冊的回撥函式。

  3. 執行回撥函式: 如果有待執行的回撥函式,瀏覽器會依次執行它們。 回撥函式會接收一個 IdleDeadline 物件作為引數。

  4. IdleDeadline 物件: 這個物件提供了兩個重要的屬性:

    • timeRemaining(): 返回當前幀剩餘的空閒時間。
    • didTimeout: 指示回撥函式是否因為超時而被執行。如果 options 中設定了 timeout,並且在 timeout 時間內回撥函式沒有被執行,則 didTimeouttrue
  5. 分片執行: 為了避免阻塞主執行緒,建議在回撥函式中執行少量的工作,並在需要繼續執行時再次呼叫 requestIdleCallback 進行下一輪的處理。 可以透過 timeRemaining() 判斷剩餘時間,如果時間不足,則停止當前工作,等待下一幀的空閒時間再次執行。

示例:

function myIdleCallback(deadline) {
  while (deadline.timeRemaining() > 0) {
    // 執行一些任務,例如處理資料、更新 UI 等
    console.log('Time remaining:', deadline.timeRemaining());
    // ...
    if (/* 任務完成 */) {
      break; // 退出迴圈
    }
  }

  if (/* 還有任務需要執行 */) {
    requestIdleCallback(myIdleCallback); // 再次註冊回撥函式
  }
}

requestIdleCallback(myIdleCallback);

總結:

requestIdleCallback 提供了一種機制,允許開發者在瀏覽器空閒時執行低優先順序的任務,例如:

  • 資料預載入
  • 延遲渲染
  • 計算密集型任務的拆分執行

透過合理利用 requestIdleCallback,可以提高網頁的效能和使用者體驗,避免阻塞主執行緒,保證頁面的流暢性。

需要注意的是,requestIdleCallback 的相容性不如其他 API 那麼好,在使用時需要考慮相容性問題,或者使用 polyfill。 而且,由於它是在空閒時間執行,所以不能保證回撥函式一定會被執行,或者執行的時機。 對於一些對實時性要求較高的任務,不建議使用 requestIdleCallback

相關文章