瀏覽器對內(nèi)容的渲染分為5個(gè)部分
- 處理 HTML 標(biāo)記并構(gòu)建 DOM 樹。
- 處理 CSS 標(biāo)記并構(gòu)建 CSSOM 樹。
- 將 DOM 與 CSSOM 合并成一個(gè)渲染樹。
- 根據(jù)渲染樹來布局,以計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息。
-
將各個(gè)節(jié)點(diǎn)繪制到屏幕上。
這五個(gè)部分并不一定按順序完成,首先瀏覽器幾乎是并行加載資源,但瀏覽器的渲染有先后。
image.png
默認(rèn)情況下,CSS 被視為阻塞渲染的資源,這意味著瀏覽器將不會渲染任何已處理的內(nèi)容,直至 CSSOM 構(gòu)建完畢。存在阻塞的 CSS 資源時(shí),瀏覽器會延遲 JavaScript 的執(zhí)行和 DOM 構(gòu)建。
而JavaScript 不僅可以讀取和修改 DOM 屬性,還可以讀取和修改 CSSOM 屬性。當(dāng)瀏覽器遇到一個(gè) script 標(biāo)記時(shí),DOM 構(gòu)建將暫停,直至腳本完成執(zhí)行。
JavaScript 可以查詢和修改 DOM 與 CSSOM。
CSSOM 構(gòu)建時(shí),JavaScript 執(zhí)行將暫停,直至 CSSOM 就緒。
所以,script 標(biāo)簽的位置很重要。實(shí)際使用時(shí),可以遵循下面兩個(gè)原則:
CSS 優(yōu)先:引入順序上,CSS 資源先于 JavaScript 資源。
JavaScript 應(yīng)盡量少影響 DOM 的構(gòu)建。
白屏&FOUC(flash of unstyled content)無樣式內(nèi)容閃爍
白屏和 fouc 是不同瀏覽器的渲染機(jī)制,不是bug
白屏:CSS全部載入解析完后渲染展示頁面。如果沒有加載完,就會出現(xiàn)白屏
FOUC:CSS未完全加載前,會先渲染顯示已經(jīng)解析的HTML內(nèi)容,然后CSS完全加載完成后,再次渲染。
repaint & reflow
當(dāng)樣式如顏色、字體等更改時(shí)瀏覽器會進(jìn)行重繪,但是當(dāng)樣式的更改涉及到尺寸的更改時(shí),會回流處理——重新計(jì)算位置,再重繪。下面是一些可能導(dǎo)致重繪和重流的樣式:
var bstyle = document.body.style;//cache
bstyle.padding = "20px";//reflow,repaint
bstyle.border="10px solid red";//reflow,repaint
bstyle.color="blue"http://repaint
bstyle.fontSize="2em";//reflow,repaint
css 會阻礙圖片的加載,而瀏覽器在遇到 js 時(shí)會立即加載并執(zhí)行指定的腳本,“立即”指的是在渲染該 script 標(biāo)簽之下的文檔元素之前,也就是說不等待后續(xù)載入的文檔元素,讀到就加載并執(zhí)行,js在加載時(shí),渲染文件的加載會停止。
但是給script標(biāo)簽增加async和defer關(guān)鍵詞后,渲染問價(jià)可以與js文件同步加載,并且使用defer關(guān)鍵詞,js的加載完成后不會馬上執(zhí)行,會等候后續(xù)所有元素解析完成后再執(zhí)行
<script async src="script.js"></script>
<script defer src="script.js"></script>
參考文獻(xiàn)
https://juejin.im/entry/59e1d31f51882578c3411c77
https://zhuanlan.zhihu.com/p/33448591
https://zhuanlan.zhihu.com/p/29418126
