瀏覽器消息隊(duì)列,宏任務(wù)與微任務(wù)

背景

每一個(gè)頁面都有一個(gè)渲染主線程,會(huì)處理很多任務(wù),比如:DOM、樣式計(jì)算、布局等等。如此多的任務(wù)就需要一個(gè)消息隊(duì)列來進(jìn)行管理。這些任務(wù)的類型,就是我們通常所說的宏任務(wù)以及微任務(wù)。

兩種任務(wù)的關(guān)系,以及他們和UI線程渲染的關(guān)系

其實(shí)宏任務(wù)以及微任務(wù)的概念在前端已經(jīng)是很普及的了,相關(guān)文章鏈接。但是有以下幾個(gè)問題一直困擾著我:

  • 宏任務(wù)以及微任務(wù)的關(guān)系
  • 這兩種任務(wù)和GUI渲染線程的關(guān)系

所以研究總結(jié)如下關(guān)系:

截屏2021-03-17 上午8.49.58.png

宏任務(wù)和他所產(chǎn)生的微任務(wù)是綁定的,一個(gè)宏任務(wù)執(zhí)行完成后,這個(gè)宏任務(wù)所產(chǎn)生的微任務(wù),以及微任務(wù)產(chǎn)生的微任務(wù)全部執(zhí)行完后。才會(huì)執(zhí)行下一個(gè)宏任務(wù)。如果這些任務(wù)耗時(shí)不長,那么一幀16ms內(nèi),可以執(zhí)行多個(gè)宏任務(wù)。

截屏2021-03-17 上午8.49.01.png

如果一個(gè)宏任務(wù)以及宏任務(wù)產(chǎn)生的微任務(wù)耗時(shí)過長,超過16ms,那么就會(huì)造成UI線程渲染阻塞。其中如果一個(gè)宏任務(wù)耗時(shí)過長,也會(huì)等待其所產(chǎn)生的微任務(wù)執(zhí)行完成后再進(jìn)行UI線程渲染頁面。

為什么要分兩種任務(wù)?

每一個(gè)任務(wù)的執(zhí)行當(dāng)中,有可能會(huì)產(chǎn)生新的任務(wù),那么這些新的任務(wù)有兩種插入消息隊(duì)列的方式:

image (1).png

這也主要是宏任務(wù)和微任務(wù)的區(qū)別,在任務(wù)執(zhí)行過程中:

  • 產(chǎn)生的宏任務(wù)直接插入消息隊(duì)列尾部依次執(zhí)行。
  • 產(chǎn)生的微任務(wù)直接插入當(dāng)前任務(wù)的微任務(wù)隊(duì)列中,在此任務(wù)執(zhí)行完成后,直接執(zhí)行此任務(wù)的微任務(wù)隊(duì)列。

可以看出微任務(wù)的存在主要是保證任務(wù)執(zhí)行的時(shí)效性,而宏任務(wù)就是正常的直接插入消息隊(duì)列尾部。

總結(jié)

  • 宏任務(wù)和微任務(wù)是綁定關(guān)系,宏任務(wù)執(zhí)行完成后會(huì)執(zhí)行它所產(chǎn)生的微任務(wù)。
  • 一幀內(nèi) (大多是16ms) ,可執(zhí)行多個(gè)宏任務(wù)以及他們的微任務(wù)。
  • 如果宏任務(wù)以及微任務(wù)執(zhí)行時(shí)間過長,那么會(huì)阻塞UI線程的工作,導(dǎo)致頁面卡頓、掉幀。
  • 宏任務(wù)產(chǎn)生的微任務(wù)直接插入當(dāng)前宏任務(wù)的微任務(wù)隊(duì)列,這么做是為了保證任務(wù)執(zhí)行的時(shí)效性。
  • 宏任務(wù)執(zhí)行過程中產(chǎn)生的宏任務(wù),會(huì)直接放入消息隊(duì)列的尾部,依次執(zhí)行,新任務(wù)的執(zhí)行時(shí)效性也就無法保證。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容