瀏覽器從接收到服務(wù)器返回的HTML
到渲染像素到屏幕上翅楼,中間經(jīng)歷了很多的步驟。瀏覽器初次繪制網(wǎng)頁(yè)的必經(jīng)過(guò)程稱之為“關(guān)鍵渲染路徑(Critical Rendering Path
酥宴,以下稱CRP
)”弯淘。
關(guān)鍵渲染路徑
CRP
有以下6個(gè)階段:
- 構(gòu)造
DOM
樹(shù) - 構(gòu)造
CSSOM
樹(shù) - 運(yùn)行
JavaScript
- 創(chuàng)建渲染樹(shù)(
Render Tree
) - 生成布局
- 繪制
一、構(gòu)造 DOM 樹(shù)
DOM
樹(shù)是一個(gè)表示完整解析過(guò)的HTML
網(wǎng)頁(yè)的對(duì)象妙痹。它從根元素<html>
開(kāi)始铸史,每一個(gè)節(jié)點(diǎn)代表頁(yè)面上的一個(gè)元素或者文本。包含在其他元素中間的元素被表示成子節(jié)點(diǎn)细诸。每一個(gè)節(jié)點(diǎn)記錄著對(duì)應(yīng)元素的所有屬性沛贪,舉例來(lái)說(shuō),一個(gè) <a>
元素對(duì)應(yīng)的節(jié)點(diǎn)包含了元素的href
屬性震贵。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<header> </header>
<section></section>
<footer></footer>
</body>
</html>
HTML
的一點(diǎn)好處是它可以分塊執(zhí)行利赋,無(wú)需加載整個(gè)文檔,內(nèi)容就可以開(kāi)始出現(xiàn)在頁(yè)面上猩系。但是不好的地方是媚送,諸如CSS
和JavaScript
文件這樣的資源,卻能夠阻塞頁(yè)面的渲染寇甸。
二塘偎、構(gòu)造 CSSOM 樹(shù)
CSSOM
(CSS 對(duì)象模型
) 是一個(gè)表示DOM
相關(guān)聯(lián)樣式的對(duì)象。它與DOM
的表現(xiàn)方式類似拿霉,但記錄了每個(gè)節(jié)點(diǎn)的關(guān)聯(lián)樣式吟秩,包含明確聲明的樣式和默認(rèn)繼承的樣式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header> </header>
<section></section>
<footer></footer>
</body>
</html>
/* style.css */
body {
font-size: 18px;
}
header {
color: plum;
}
section {
color: firebrick;
}
footer {
display: none;
}
CSS
文件只有適用于當(dāng)前設(shè)備的時(shí)候才會(huì)被認(rèn)為是 ”渲染阻塞資源“ 绽淘。<link rel="stylesheet">
標(biāo)簽可以接受一個(gè)媒體屬性涵防,通過(guò)改屬性我們可以聲明樣式表適用的設(shè)備。例如:我們有個(gè)樣式表聲明了一個(gè)媒體屬性orientation:landscape
, 只有我們?cè)诳v向模式訪問(wèn)的時(shí)候沪铭,該資源才是阻塞渲染的壮池。
由于Javascript
文件必須等待CSSOM
構(gòu)建完成才能夠運(yùn)行偏瓤。因此也可以說(shuō)CSS
是 “阻塞腳本”的。
三椰憋、運(yùn)行 Javascript
JavaScript
被認(rèn)為是一種 解析阻塞資源厅克,HTML
本身的解析會(huì)被JavaScript
阻塞。
當(dāng)解析器遇到<script>
標(biāo)簽時(shí)橙依,不管是內(nèi)部腳本還是外部腳本证舟,解析器會(huì)停下來(lái)加載腳本(是外部腳本的情況下)并運(yùn)行它。這就是為什么我們必須將哪些需要引用Element
和文檔的腳本放在文檔外觀的后面票编。
為了避免 Javascript
阻塞解析褪储,通過(guò)聲明async
屬性,可以讓它被異步加載慧域。
<script async src="script.js">
四鲤竹、創(chuàng)建渲染樹(shù)
渲染樹(shù)是 DOM
和 CSSOM
的結(jié)合。它是一個(gè)表示頁(yè)面被最終渲染效果的樹(shù)昔榴。這意味著它只會(huì)表示哪些可見(jiàn)的內(nèi)容辛藻,哪些不可見(jiàn)內(nèi)容,比如聲明了display:none;
的元素互订。
使用前面例子中提到的 DOM
和CSSDOM
吱肌,下面的渲染樹(shù)會(huì)被創(chuàng)建出來(lái)。
五仰禽、生成布局
布局決定了視窗(viewport
)的大小氮墨,它提供了 CSS
樣式依賴的上下文,例如視窗的百分比或者單位吐葵。
視窗的大小由在文檔頭部提供的meta
標(biāo)簽 viewport
決定规揪,在移動(dòng)端,如果不設(shè)置viewport
寬度為理想視口温峭,viewport
寬度通常為980px
猛铅,這會(huì)導(dǎo)致文字很小,我們需要手動(dòng)放大閱讀凤藏。
舉例奸忽,常用于響應(yīng)設(shè)備寬度的視窗設(shè)置如下:
<meta name="viewport" content="width=device-width,initial-scale=1">
六、繪制
最終的步驟是繪制揖庄,頁(yè)面的可見(jiàn)內(nèi)容會(huì)被轉(zhuǎn)化成屏幕上的像素栗菜。
繪制過(guò)程的耗時(shí)取決于DOM
的大小和應(yīng)用的樣式。某些樣式比其他樣式需要更多的處理過(guò)程蹄梢。例如:復(fù)雜的漸變背景圖比簡(jiǎn)單的填充背景需要消耗更多的處理時(shí)間疙筹。