摘要:而進(jìn)程是多線程的,它主要包含以下主要線程渲染線程負(fù)責(zé)渲染瀏覽器界面,解析,,構(gòu)建樹(shù)和樹(shù),布局和繪制等。且加載解析執(zhí)行會(huì)阻止解析器往下執(zhí)行,要強(qiáng)調(diào)渲染和下載是不沖突的,渲染是線程在執(zhí)行,下載是下載線程在執(zhí)行,瀏覽器多線程。
了解瀏覽器線程基礎(chǔ)
一個(gè)頁(yè)面的呈現(xiàn)主要是由瀏覽器渲染進(jìn)程實(shí)現(xiàn)的(render進(jìn)程),主要作用為頁(yè)面的渲染,腳本執(zhí)行,事件處理等。而render進(jìn)程是多線程的,它主要包含以下主要線程:
1 GUI渲染線程
負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹(shù)和RenderObject樹(shù),布局和繪制等。
當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時(shí),該線程就會(huì)執(zhí)行
注意,GUI渲染線程與JS引擎線程是互斥的,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起(相當(dāng)于被凍 結(jié)了),GUI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行。
2 JS引擎線程
也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序。(例如V8引擎)
JS引擎線程負(fù)責(zé)解析Javascript腳本,運(yùn)行代碼。
JS引擎一直等待著任務(wù)隊(duì)列中任務(wù)的到來(lái),然后加以處理,一個(gè)Tab頁(yè)(renderer進(jìn)程)中 無(wú)論什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序
同樣注意,GUI渲染線程與JS引擎線程是互斥的,所以如果JS執(zhí)行的時(shí)間過(guò)長(zhǎng),這樣就會(huì)造成頁(yè)面的渲染不連貫,導(dǎo)致頁(yè)面渲染加載阻塞。
3 事件觸發(fā)線程
歸屬于瀏覽器而不是JS引擎,用來(lái)控制事件循環(huán)(可以理解,JS引擎自己都忙不過(guò)來(lái),需要瀏覽器另開(kāi)線程協(xié)助)
當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(shí)(也可來(lái)自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點(diǎn)擊、AJAX異步請(qǐng)求等),會(huì)將對(duì)應(yīng)任務(wù)添加到事件線程中
當(dāng)對(duì)應(yīng)的事件符合觸發(fā)條件被觸發(fā)時(shí),該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾,等待JS引擎的處理
注意,由于JS的單線程關(guān)系,所以這些待處理隊(duì)列中的事件都得排隊(duì)等待JS引擎處理(當(dāng)JS引擎空閑時(shí)才會(huì)去執(zhí)行)
4 定時(shí)觸發(fā)器線程
傳說(shuō)中的setInterval與setTimeout所在線程
瀏覽器定時(shí)計(jì)數(shù)器并不是由JavaScript引擎計(jì)數(shù)的,(因?yàn)镴avaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會(huì)影響記計(jì)時(shí)的準(zhǔn)確)
因此通過(guò)多帶帶線程來(lái)計(jì)時(shí)并觸發(fā)定時(shí)(計(jì)時(shí)完畢后,添加到事件隊(duì)列中,等待JS引擎空閑后執(zhí)行)
5 異步http請(qǐng)求線程
在XMLHttpRequest在連接后是通過(guò)瀏覽器新開(kāi)一個(gè)線程請(qǐng)求
將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件隊(duì)列中。再由JavaScript引擎執(zhí)行。
JS阻塞特性由上述GUI線程和JS引擎互斥的關(guān)系,我們也就能更好的理解為什么JS運(yùn)行會(huì)阻塞頁(yè)面的渲染,也就是常說(shuō)的JS阻塞特性。
HTML整體執(zhí)行步驟0.加載整體html文件
1.至上而下解析html
2.解析html建立dom樹(shù),遇到諸如
html順序測(cè)試