requestAnimationFrame和requestIdleCallback是宏任務(wù)還是微任務(wù)

一岸蜗、思考

大家都知道異步任務(wù)分為宏任務(wù)和微任務(wù)备蚓,不知道的可以看我的另一篇文章(深入理解Event Loop的運行機制
要搞清楚requestAnimationFrame和requestIdleCallback是宏任務(wù)還是微任務(wù)就必須要搞清楚下面幾個問題:

  1. 瀏覽器在每一輪Event Loop事件循環(huán)中都會去渲染屏幕嗎?
  2. requestAnimationFrame在哪個階段執(zhí)行,是在渲染前還是渲染后?是在微任務(wù)執(zhí)行前還是執(zhí)行后良姆?
  3. requestIdleCallback在哪個階段執(zhí)行,是在渲染前還是渲染后穴肘? 是在微任務(wù)執(zhí)行前還是執(zhí)行后歇盼?

二、任務(wù)的執(zhí)行時機

在瀏覽器的Event Loop中是有多個任務(wù)隊列的评抚,每個任務(wù)隊列的執(zhí)行時機是不一樣的豹缀,下面直接上干貨,說說瀏覽器執(zhí)行任務(wù)的順序

  1. 從task任務(wù)隊列中取第一個task(比如setTimeout慨代、setIntervel的回調(diào)邢笙,也可以將同一輪循環(huán)中的所有同步代碼看作是一個宏任務(wù)),執(zhí)行它侍匙。
  2. 執(zhí)行微任務(wù)隊列里的所有微任務(wù)氮惯。
  3. 瀏覽器判斷是否更新渲染屏幕,如果需要重新繪制想暗,則執(zhí)行步驟4-13妇汗,如果不需要重新繪制,則流程回到步驟1说莫,這樣不斷循環(huán)杨箭。
  4. 觸發(fā)resize、scroll事件储狭,建立媒體查詢(執(zhí)行一個任務(wù)中如果生成了微任務(wù)互婿,則執(zhí)行完任務(wù)該后就會執(zhí)行所有的微任務(wù),然后再執(zhí)行下一個任務(wù))辽狈。
  5. 建立css動畫(執(zhí)行一個任務(wù)中如果生成了微任務(wù)慈参,則執(zhí)行完該任務(wù)后就會執(zhí)行所有的微任務(wù),然后再執(zhí)行下一個任務(wù))刮萌。
  6. 執(zhí)行requestAnimationFrame回調(diào)(執(zhí)行一個任務(wù)中如果生成了微任務(wù)驮配,則執(zhí)行完該任務(wù)后就會執(zhí)行所有的微任務(wù),然后再執(zhí)行下一個任務(wù))着茸。
  7. 執(zhí)行 IntersectionObserver 回調(diào)(執(zhí)行一個任務(wù)中如果生成了微任務(wù)僧凤,則執(zhí)行完該任務(wù)后就會執(zhí)行所有的微任務(wù),然后再執(zhí)行下一個任務(wù))元扔。
  8. 更新渲染屏幕。
  9. 瀏覽器判斷當(dāng)前幀是否還有空閑時間旋膳,如果有空閑時間澎语,則執(zhí)行步驟10-12。
  10. 從 requestIdleCallback回調(diào)函數(shù)隊列中取第一個,執(zhí)行它擅羞。
  11. 執(zhí)行微任務(wù)隊列里的所有微任務(wù)尸变。
  12. 流程回到步驟9,直到requestIdleCallback回調(diào)函數(shù)隊列清空或當(dāng)前幀沒有空閑時間减俏。
  13. 流程回到步驟1召烂,這樣不斷循環(huán)。

三娃承、代碼驗證

我們可以寫一些代碼到Chrome瀏覽器中驗證一下奏夫,看看requestAnimationFrame和requestIdleCallback的執(zhí)行順序是怎樣的。

運行以下這段代碼

requestAnimationFrame(()=>{
    console.log(111);
    setTimeout(() => {
        console.log(222);
    });
    Promise.resolve().then(() => {
        console.log(333);
    });
})

requestAnimationFrame(() => {
    console.log(444);
    Promise.resolve().then(() => {
        console.log(555);
    });
})

輸出結(jié)果

運行以下這段代碼

requestIdleCallback(() => {
    console.log(111);
    setTimeout(() => {
        console.log(222);
    })
    Promise.resolve().then(() => {
        console.log(333);
    })
})

requestIdleCallback(() => {
    console.log(444);
    Promise.resolve().then(() => {
        console.log(555);
    })
})

輸出結(jié)果

運行以下這段代碼

Promise.resolve().then(() => {
    console.log(111);
    setTimeout(() => {
        console.log(222);
    })
    Promise.resolve().then(() => {
        console.log(333);
    })
})

Promise.resolve().then(() => {
    console.log(444);
    Promise.resolve().then(() => {
        console.log(555);
    })
})

輸出結(jié)果

四历筝、總結(jié)

  1. requestAnimationFrame和requestIdleCallback是和宏任務(wù)性質(zhì)一樣的任務(wù)酗昼,只是他們的執(zhí)行時機不同而已。也有人說它們既不是宏任務(wù)也不是微任務(wù)梳猪,其實我們不必糾結(jié)這個麻削,我們所要做的就是知道他們的執(zhí)行時機就好。
  2. 瀏覽器在每一輪Event Loop事件循環(huán)中不一定會去重新渲染屏幕春弥,會根據(jù)瀏覽器刷新率以及頁面性能或是否后臺運行等因素判斷的呛哟,瀏覽器的每一幀是比較固定的,會盡量保持60Hz的刷新率運行匿沛,每一幀中間可能會進行多輪事件循環(huán)扫责。
  3. requestAnimationFrame回調(diào)的執(zhí)行與task和microtask無關(guān),而是與瀏覽器是否渲染相關(guān)聯(lián)的俺祠。它是在瀏覽器渲染前公给,在微任務(wù)執(zhí)行后執(zhí)行。
  4. requestIdleCallback是在瀏覽器渲染后有空閑時間時執(zhí)行蜘渣,如果requestIdleCallback設(shè)置了第二個參數(shù)timeout淌铐,則會在超時后的下一幀強制執(zhí)行。

更多個人文章

  1. 兩個跨域頁面進行跳轉(zhuǎn)傳參的終極方案
  2. 徹底搞懂盒子模型
  3. hashHistory和browserHistory的區(qū)別
  4. 面試秘籍之手寫系列
  5. 十分鐘帶你入門Chrome插件開發(fā)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔫缸,一起剝皮案震驚了整個濱河市腿准,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拾碌,老刑警劉巖吐葱,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異校翔,居然都是意外死亡弟跑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門防症,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孟辑,“玉大人哎甲,你說我怎么就攤上這事∷撬裕” “怎么了炭玫?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長貌虾。 經(jīng)常有香客問我吞加,道長,這世上最難降的妖魔是什么尽狠? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任衔憨,我火速辦了婚禮,結(jié)果婚禮上晚唇,老公的妹妹穿的比我還像新娘巫财。我一直安慰自己,他們只是感情好哩陕,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布平项。 她就那樣靜靜地躺著,像睡著了一般悍及。 火紅的嫁衣襯著肌膚如雪闽瓢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天心赶,我揣著相機與錄音扣讼,去河邊找鬼。 笑死缨叫,一個胖子當(dāng)著我的面吹牛椭符,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耻姥,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼销钝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了琐簇?” 一聲冷哼從身側(cè)響起蒸健,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婉商,沒想到半個月后似忧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡丈秩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年盯捌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蘑秽。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡饺著,死狀恐怖滤祖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓶籽,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布埂材,位于F島的核電站塑顺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏俏险。R本人自食惡果不足惜严拒,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望竖独。 院中可真熱鬧裤唠,春花似錦、人聲如沸莹痢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竞膳。三九已至航瞭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坦辟,已是汗流浹背刊侯。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锉走,地道東北人滨彻。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像挪蹭,于是被迫代替她去往敵國和親亭饵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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