JS原生Background Tasks

一.window.requestIdleCallback

1.作用:

這個方法將會在瀏覽器的空閑時間調(diào)用函數(shù)排隊魁袜。這樣可以使操作者在主事件循環(huán)上執(zhí)行后臺和低優(yōu)先級工作并淋,而不會影響延遲關(guān)鍵事件持舆,比如動畫和輸入響應(yīng),函數(shù)一般會按照先進(jìn)先執(zhí)行的順序進(jìn)行調(diào)用,但是如果設(shè)置了timeout(超時執(zhí)行時間)呆奕,將會導(dǎo)致為了在超時之前執(zhí)行相應(yīng)的函數(shù)操作而打亂執(zhí)行順序峰尝。

2.使用方法

window.requestIdleCallback(callback,option)
參數(shù)
callback:一個在瀏覽器空閑時即將被調(diào)用的函數(shù)引用函數(shù)會接收到一個名為IdleDeadline的參數(shù)偏窝,這個參數(shù)可以獲取當(dāng)前空閑時間以及回調(diào)是否在超時時間前已經(jīng)執(zhí)行的狀態(tài)。(IdleDeadline對象包括didTimeout武学,是一個布爾值表示任務(wù)是否超時祭往;以及timeRemaining(),表示當(dāng)前幀剩余的時間火窒,是留給任務(wù)執(zhí)行的時間)
option:配置項硼补,可以配置timeout,是可選參數(shù)(timeout:如果指定了timeout并具有一個正值熏矿,并且尚未通過超時毫秒數(shù)調(diào)用回調(diào)已骇,那么回調(diào)會在下一次空閑時期被強(qiáng)制執(zhí)行离钝,盡管這樣很可能會對性能造成負(fù)面影響。
返回值:
一個ID褪储,可以通過window.cancelIdleCallback()來結(jié)束回調(diào)

requestIdleCallback(myNonEssentialWork, { timeout: 2000 });

// 任務(wù)隊列
const tasks = [
 () => {
   console.log("第一個任務(wù)");
 },
 () => {
   console.log("第二個任務(wù)");
 },
 () => {
   console.log("第三個任務(wù)");
 },
];

function myNonEssentialWork (deadline) {
 // 如果幀內(nèi)有富余的時間卵渴,或者超時
 while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0) {
   work();
 }

 if (tasks.length > 0)
   requestIdleCallback(myNonEssentialWork);
 }

function work () {
 tasks.shift()();
 console.log('執(zhí)行任務(wù)');
}

3.使用setTimeout模擬實現(xiàn)

window.requestIdleCallback = window.requestIdleCallback || function(handler) {
  let startTime = Date.now();
 
  return setTimeout(function() {
    handler({
      didTimeout: false,
      timeRemaining: function() {
        return Math.max(0, 50.0 - (Date.now() - startTime));
      }
    });
  }, 1);
}

可以在 ric 中執(zhí)行任務(wù)時需要注意以下幾點
1.執(zhí)行重計算而非緊急任務(wù)
2.空閑回調(diào)執(zhí)行時間應(yīng)該小于 50ms,最好更少
3.空閑回調(diào)中不要操作 DOM鲤竹,因為它本來就是利用的重拍重繪后的間隙空閑時間浪读,重新操作 DOM 又會造成重拍重繪,DOM 操作建議在 rAF 中進(jìn)行辛藻。同時碘橘,操作 DOM 所需要的耗時是不確定的,因為會導(dǎo)致重新計算布局和視圖的繪制揩尸,所以這類操作不具備可預(yù)測性蛹屿。
4.Promise 也不建議在這里面進(jìn)行,因為 Promise 的回調(diào)屬性 Event loop 中優(yōu)先級較高的一種微任務(wù)岩榆,會在 requestIdleCallback 結(jié)束時立即執(zhí)行错负,不管此時是否還有富余的時間,這樣有很大可能會讓一幀超過 16 ms勇边。
React 的時間分片便是基于類似 requestIdleCallback 而實現(xiàn)犹撒,然而因為 ric 的兼容性及 50ms 流暢問題,React 自制了一個實現(xiàn): scheduler

二.window.requestAnimationFrame

1.作用:

通知瀏覽器粒褒,要求在下一次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動畫识颊。如果希望在下一次重繪之前更新下一幀動畫,那么需要回調(diào)函數(shù)自身必須再次調(diào)用window.requestAnimationFrame(),當(dāng)window.requestAnimationFrame運(yùn)行在后臺標(biāo)簽或者隱藏的iframe時奕坟,會被暫停來提高性能

2.用法

window.requestAnimationFrame(callback)
參數(shù):
callback:下一次重繪之前更新動畫幀所調(diào)用的函數(shù)祥款。該回調(diào)函數(shù)會被傳入DOMHighResTimeStamp參數(shù),它表示的是開始執(zhí)行回調(diào)函數(shù)的時刻
返回值:
一個ID月杉,可以傳入window.cancelAnimationFrame()以取消回調(diào)函數(shù)刃跛。

3.補(bǔ)充

以往我們執(zhí)行動畫動畫時所采用的操作是setTimeout和setInterval,這種做法的弊端就是:回調(diào)函數(shù)執(zhí)行時間是不固定的,有可能剛好就卡在末尾或者不再執(zhí)行了苛萎,會引起丟幀和卡頓


歸根到底發(fā)生上面這個問題的原因在于時機(jī)桨昙,也就是瀏覽器要知道何時對回調(diào)函數(shù)進(jìn)行響應(yīng)。setTimeoutsetInterval 是使用定時器來觸發(fā)回調(diào)函數(shù)的腌歉,而定時器并無法保證能夠準(zhǔn)確無誤的執(zhí)行蛙酪,有許多因素會影響它的運(yùn)行時機(jī),比如說:當(dāng)有同步代碼執(zhí)行時翘盖,會先等同步代碼執(zhí)行完畢桂塞,異步隊列中沒有其他任務(wù),才會輪到自己執(zhí)行馍驯。并且藐俺,我們知道每一次重新渲染的最佳時間大約是 16.6 ms炊甲,如果定時器的時間間隔過短,就會造成 過度渲染欲芹,增加開銷;過長又會延遲渲染吟吝,使動畫不流暢菱父。

requestAnimationFrame 方法不同與 setTimeout 或 setInterval,它是由系統(tǒng)來決定回調(diào)函數(shù)的執(zhí)行時機(jī)的剑逃,會請求瀏覽器在下一次重新渲染之前執(zhí)行回調(diào)函數(shù)浙宜。無論設(shè)備的刷新率是多少,requestAnimationFrame 的時間間隔都會緊跟屏幕刷新一次所需要的時間蛹磺;例如某一設(shè)備的刷新率是 75 Hz粟瞬,那這時的時間間隔就是 13.3 ms(1 秒 / 75 次)。需要注意的是這個方法雖然能夠保證回調(diào)函數(shù)在每一幀內(nèi)只渲染一次萤捆,但是如果這一幀有太多任務(wù)執(zhí)行裙品,還是會造成卡頓的;因此它只能保證重新渲染的時間間隔最短是屏幕的刷新時間俗或。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末市怎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子辛慰,更是在濱河造成了極大的恐慌区匠,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帅腌,死亡現(xiàn)場離奇詭異驰弄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)速客,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門戚篙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挽封,你說我怎么就攤上這事已球。” “怎么了辅愿?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵智亮,是天一觀的道長。 經(jīng)常有香客問我点待,道長阔蛉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任癞埠,我火速辦了婚禮状原,結(jié)果婚禮上聋呢,老公的妹妹穿的比我還像新娘。我一直安慰自己颠区,他們只是感情好削锰,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著毕莱,像睡著了一般器贩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上朋截,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天蛹稍,我揣著相機(jī)與錄音,去河邊找鬼部服。 笑死唆姐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的廓八。 我是一名探鬼主播奉芦,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瘫想!你這毒婦竟也來了仗阅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤国夜,失蹤者是張志新(化名)和其女友劉穎减噪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體车吹,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡筹裕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窄驹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朝卒。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乐埠,靈堂內(nèi)的尸體忽然破棺而出抗斤,到底是詐尸還是另有隱情,我是刑警寧澤丈咐,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布瑞眼,位于F島的核電站,受9級特大地震影響棵逊,放射性物質(zhì)發(fā)生泄漏伤疙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望徒像。 院中可真熱鬧黍特,春花似錦、人聲如沸锯蛀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谬墙。三九已至今布,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拭抬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工侵蒙, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留造虎,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓纷闺,卻偏偏與公主長得像算凿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子犁功,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 這種網(wǎng)頁響應(yīng)非常緩慢氓轰,占用大量的CPU和內(nèi)存,瀏覽起來常常有卡頓浸卦,頁面的動畫效果也不流暢署鸡。 你會有什么反應(yīng)?我猜想...
    零一間閱讀 125評論 0 1
  • 一限嫌、網(wǎng)頁生成的過程 要理解網(wǎng)頁性能為什么不好靴庆,就要了解網(wǎng)頁是怎么生成的?網(wǎng)頁的生成過程怒医,大概可以分成五步 1.HT...
    silly鴻閱讀 526評論 0 0
  • 標(biāo)簽: 你遇到過性能很差的網(wǎng)頁嗎炉抒? 這種網(wǎng)頁響應(yīng)非常緩慢,占用大量的CPU和內(nèi)存稚叹,瀏覽起來常常有卡頓焰薄,頁面的動畫效...
    Bruce_zhuan閱讀 1,086評論 3 12
  • 你遇到過性能很差的網(wǎng)頁嗎? 這種網(wǎng)頁響應(yīng)非常緩慢扒袖,占用大量的 CPU 和內(nèi)存塞茅,瀏覽起來常常有卡頓,頁面的動畫效果也...
    Mr丶Sunny閱讀 304評論 0 1
  • 概念:重排(reflow):重新生成布局重繪(repaint):重新繪制"重繪"不一定需要"重排"僚稿,比如改變某個網(wǎng)...
    索哥來了閱讀 267評論 0 0