新聞中心
本文轉(zhuǎn)載自微信公眾號(hào)「三分鐘學(xué)前端」,作者sisterAn 。轉(zhuǎn)載本文請(qǐng)聯(lián)系三分鐘學(xué)前端公眾號(hào)。

瀏覽器的渲染
瀏覽器的渲染流程如下:
圖:WebKit 主流程
圖:Mozilla 的 Gecko 呈現(xiàn)引擎主流程(3.6)
結(jié)合上圖,一個(gè)完整的渲染流程如下:
- 渲染進(jìn)程解析 HTML 內(nèi)容轉(zhuǎn)換為能夠讀懂的 DOM 樹(shù)結(jié)構(gòu),解析 CSS 為 CSSDOM
- 把 DOM 和 CSSOM 結(jié)合起來(lái)生成渲染樹(shù)(Render Tree)
- 渲染樹(shù)構(gòu)建好了之后,將會(huì)執(zhí)行布局過(guò)程,它將確定每個(gè)節(jié)點(diǎn)在屏幕上的確切坐標(biāo)
- 把渲染樹(shù)展示到屏幕上。再下一步就是繪制,即遍歷渲染樹(shù),并使用UI后端層繪制每個(gè)節(jié)點(diǎn)。
值得注意的是:
關(guān)鍵的點(diǎn)在于上述的 4 步并不是以嚴(yán)格順序執(zhí)行的。渲染引擎會(huì)以最快的速度展示內(nèi)容,也就是說(shuō),瀏覽器一邊解析 HTML,一邊構(gòu)建渲染樹(shù),構(gòu)建一部分,就會(huì)把當(dāng)前已有的元素渲染出來(lái)。如果這個(gè)時(shí)候外部樣式并沒(méi)有加載完成,渲染出來(lái)的就是瀏覽器默認(rèn)樣式了。
其它階段也是如此。由于瀏覽器會(huì)嘗試盡快展示內(nèi)容,所以?xún)?nèi)容有時(shí)會(huì)在樣式還沒(méi)有加載的時(shí)候展示出來(lái)。這就是經(jīng)常發(fā)生的FOCU(flash of unstyled content)或白屏問(wèn)題。
CSS 加載不會(huì)阻塞 DOM 樹(shù)的解析
由瀏覽器的渲染流程圖可知,DOM 解析和 CSS 解析是兩個(gè)并行的進(jìn)程,所以 CSS 加載不會(huì)阻塞 DOM 樹(shù)的解析
CSS 加載會(huì)阻塞 DOM 樹(shù)的渲染
Render Tree是依賴(lài)于 DOM Tree 和 CSSOM Tree 的,所以無(wú)論 DOM Tree 是否已經(jīng)完成,它都必須等待到 CSSOM Tree 構(gòu)建完成,即 CSS 加載完成(或 CSS 加載失敗)后,才能開(kāi)始渲染。
因此,CSS加載是會(huì)阻塞 DOM 樹(shù)的渲染
hello world
案例來(lái)源:關(guān)于 JS 與 CSS 是否阻塞 DOM 的渲染和解析
CSS 的加載并沒(méi)有阻塞 DOM 樹(shù)的解析,p 標(biāo)簽是正常解析的,但 p 標(biāo)簽加載完后,頁(yè)面是遲遲沒(méi)有渲染的,是因?yàn)?CSS 還沒(méi)有請(qǐng)求完成,在 CSS 請(qǐng)求完成后,hello world 才被渲染出來(lái),所以 CSS 會(huì)阻塞頁(yè)面渲染
DOMContentLoaded:只有當(dāng)純 HTML 被完全加載以及解析時(shí),DOMContentLoaded 事件會(huì)被觸發(fā),它不會(huì)等待樣式表,圖片或者子框架完成加載
CSS 加載會(huì)阻塞其后的 JS 執(zhí)行
由瀏覽器的渲染流程圖可知,JS 的加載、解析與執(zhí)行會(huì)阻塞 DOM 的構(gòu)建,也就是說(shuō),在構(gòu)建 DOM 時(shí),HTML 解析器若遇到了 JS,那么它會(huì)暫停構(gòu)建 DOM ,將控制權(quán)移交給JS引擎,等 JS 引擎運(yùn)行完畢,瀏覽器再?gòu)闹袛嗟牡胤交謴?fù) DOM 構(gòu)建。
這也是建議將 script 標(biāo)簽放在 body 標(biāo)簽底部的原因。
由瀏覽器的渲染流程圖可知,DOM 和 CSSOM 的構(gòu)建是互不影響,但如果在 JS 腳本前引入外部 CSS 文件?
hello world hello world
它的執(zhí)行流程:
此時(shí) CSS 也阻塞 DOM 的生成
這是因?yàn)?JS 不只是可以改 DOM ,它還可以更改樣式,也就是它可以更改 CSSOM 。而不完整的 CSSOM 是無(wú)法使用的, JS 中想訪問(wèn) CSSOM 并更改它,那么在執(zhí)行 JS 時(shí),必須要能拿到完整的CSSOM。
所以就導(dǎo)致了一個(gè)現(xiàn)象,如果瀏覽器尚未完成 CSSOM 的下載和構(gòu)建,而我們卻想在此時(shí)運(yùn)行腳本,那么瀏覽器將延遲腳本執(zhí)行和 DOM 構(gòu)建,直至其完成 CSSOM 的下載和構(gòu)建。也就是說(shuō),在這種情況下,瀏覽器會(huì)先下載和構(gòu)建 CSSOM ,然后再執(zhí)行JS腳本,最后在繼續(xù)構(gòu)建 DOM 。
如果也有 JS 加載喃?
hello world
HTML 文件中包含了 CSS 的外部引用和 JS 外部文件,HTML 同時(shí)發(fā)起這兩個(gè)文件的下載請(qǐng)求,不管 CSS 文件和 JS 文件誰(shuí)先到達(dá),都要先等到 CSS 文件下載完成并生成 CSSOM,然后再執(zhí)行 JavaScript 腳本,最后再繼續(xù)構(gòu)建 DOM,構(gòu)建布局樹(shù),繪制頁(yè)面。
所以一般將


咨詢(xún)
建站咨詢(xún)