還有一個函數(shù)window.requestIdleCallback(),也可以用來調(diào)節(jié)重新渲染。
它指定只有當一幀的末尾有空閑時間,才會執(zhí)行回調(diào)函數(shù)。
requestIdleCallback(fn);
上面代碼中,只有當前幀的運行時間小于16.66ms時,函數(shù)fn才會執(zhí)行。否則,就推遲到下一幀,如果下一幀也沒有空閑時間,就推遲到下下一幀,以此類推。
它還可以接受第二個參數(shù),表示指定的毫秒數(shù)。如果在指定 的這段時間之內(nèi),每一幀都沒有空閑時間,那么函數(shù)fn將會強制執(zhí)行。
requestIdleCallback(fn, 5000);
上面的代碼表示,函數(shù)fn最遲會在5000毫秒之后執(zhí)行。
函數(shù) fn 可以接受一個 deadline 對象作為參數(shù)。
requestIdleCallback(function someHeavyComputation(deadline) {
while(deadline.timeRemaining() > 0) {
doWorkIfNeeded();
}
if(thereIsMoreWorkToDo) {
requestIdleCallback(someHeavyComputation);
}
});
上面代碼中,回調(diào)函數(shù) someHeavyComputation 的參數(shù)是一個 deadline 對象。
deadline對象有一個方法和一個屬性:timeRemaining() 和 didTimeout。
(1)timeRemaining() 方法
timeRemaining() 方法返回當前幀還剩余的毫秒。這個方法只能讀,不能寫,而且會動態(tài)更新。因此可以不斷檢查這個屬性,如果還有剩余時間的話,就不斷執(zhí)行某些任務(wù)。一旦這個屬性等于0,就把任務(wù)分配到下一輪requestIdleCallback
。
前面的示例代碼之中,只要當前幀還有空閑時間,就不斷調(diào)用doWorkIfNeeded方法。一旦沒有空閑時間,但是任務(wù)還沒有全執(zhí)行,就分配到下一輪requestIdleCallback
。
(2)didTimeout屬性
deadline對象的?didTimeout
?屬性會返回一個布爾值,表示指定的時間是否過期。這意味著,如果回調(diào)函數(shù)由于指定時間過期而觸發(fā),那么你會得到兩個結(jié)果。
- timeRemaining方法返回0
- didTimeout 屬性等于 true
因此,如果回調(diào)函數(shù)執(zhí)行了,無非是兩種原因:當前幀有空閑時間,或者指定時間到了。
function myNonEssentialWork (deadline) {
while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0)
doWorkIfNeeded();
if (tasks.length > 0)
requestIdleCallback(myNonEssentialWork);
}
requestIdleCallback(myNonEssentialWork, 5000);
上面代碼確保了,doWorkIfNeeded 函數(shù)一定會在將來某個比較空閑的時間(或者在指定時間過期后)得到反復(fù)執(zhí)行。
requestIdleCallback 是一個很新的函數(shù),剛剛引入標準,目前只有Chrome支持。
更多建議: