requestIdleCallback
在瀏覽器的事件迴圈(Event Loop)中,空閒階段(Idle Phase) 執行。 它會在瀏覽器完成其他高優先順序任務(例如處理使用者輸入、渲染頁面、執行 JavaScript 等)後,並且有剩餘時間時才會被呼叫。
執行方式:
-
註冊回撥函式: 使用
requestIdleCallback(callback, options)
註冊一個回撥函式callback
。options
可選,用於設定超時時間。 -
空閒階段呼叫: 瀏覽器在完成一個事件迴圈的 tasks、microtasks 佇列後,如果還有剩餘時間,就會進入空閒階段。這時,它會檢查是否有透過
requestIdleCallback
註冊的回撥函式。 -
執行回撥函式: 如果有待執行的回撥函式,瀏覽器會依次執行它們。 回撥函式會接收一個
IdleDeadline
物件作為引數。 -
IdleDeadline
物件: 這個物件提供了兩個重要的屬性:timeRemaining()
: 返回當前幀剩餘的空閒時間。didTimeout
: 指示回撥函式是否因為超時而被執行。如果options
中設定了timeout
,並且在timeout
時間內回撥函式沒有被執行,則didTimeout
為true
。
-
分片執行: 為了避免阻塞主執行緒,建議在回撥函式中執行少量的工作,並在需要繼續執行時再次呼叫
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
。