HTML頁(yè)面加載和解析流程
(1). 用戶輸入網(wǎng)址(假設(shè)是個(gè)html頁(yè)面,并且是第一次訪問(wèn)),瀏覽器向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器返回html文件;
(2). 瀏覽器開(kāi)始載入html代碼滑肉,發(fā)現(xiàn)<head>標(biāo)簽內(nèi)有一個(gè)<link>標(biāo)簽引用外部CSS文件;
(3). 瀏覽器又發(fā)出CSS文件的請(qǐng)求摘仅,服務(wù)器返回這個(gè)CSS文件靶庙;
(4). 瀏覽器繼續(xù)載入html中<body>部分的代碼,并且CSS文件已經(jīng)拿到手了实檀,可以開(kāi)始渲染頁(yè)面了惶洲;
(5). 瀏覽器在代碼中發(fā)現(xiàn)一個(gè)<img>標(biāo)簽引用了一張圖片,向服務(wù)器發(fā)出請(qǐng)求膳犹。此時(shí)瀏覽器不會(huì)等到圖片下載完恬吕,而是繼續(xù)渲染后面的代碼;
(6). 服務(wù)器返回圖片文件须床,由于圖片占用了一定面積铐料,影響了后面段落的排布,因此瀏覽器需要回過(guò)頭來(lái)重新渲染這部分代碼豺旬;
(7). 瀏覽器發(fā)現(xiàn)了一個(gè)包含一行Javascript代碼的<script>標(biāo)簽钠惩,趕快運(yùn)行它;
(8). Javascript腳本執(zhí)行了這條語(yǔ)句族阅,它命令瀏覽器隱藏掉代碼中的某個(gè)<div> (style.display=”none”)篓跛。突然少了這么一個(gè)元素,瀏覽器不得不重新渲染這部分
代碼坦刀;
(9). 終于等到了</html>的到來(lái)愧沟,瀏覽器淚流滿面……
(10). 等等,還沒(méi)完鲤遥,用戶點(diǎn)了一下界面中的“換膚”按鈕沐寺,Javascript讓瀏覽器換了一下<link>標(biāo)簽的CSS路徑;
(11). 瀏覽器召集了在座的各位<div><span><ul><li>們盖奈,“大伙兒收拾收拾行李混坞,咱得重新來(lái)過(guò)……”,瀏覽器向服務(wù)器請(qǐng)求了新的CSS文件,重新渲染頁(yè)面究孕。
上述這個(gè)過(guò)程是逐步完成的啥酱,為了更好的用戶體驗(yàn),渲染引擎將會(huì)盡可能早的將內(nèi)容呈現(xiàn)到屏幕上厨诸,并不會(huì)等到所有的html都解析完成之后再去構(gòu)建和布局render樹(shù)懈涛。
它是解析完一部分內(nèi)容就顯示一部分內(nèi)容,同時(shí)泳猬,可能還在通過(guò)網(wǎng)絡(luò)下載其余內(nèi)容。
javascript的加載和執(zhí)行的特點(diǎn):
(1)載入后馬上執(zhí)行宇植;
(2)執(zhí)行時(shí)會(huì)阻塞頁(yè)面后續(xù)的內(nèi)容(包括頁(yè)面的渲染得封、其它資源的下載)。原因:因?yàn)闉g覽器需要一個(gè)穩(wěn)定的DOM樹(shù)結(jié)構(gòu)指郁,而JS中很有可能有 代碼直接改變了DOM樹(shù)結(jié)構(gòu)忙上,
比如使用 document.write 或 appendChild,甚至是直接使用的location.href進(jìn)行跳轉(zhuǎn),瀏覽器為了防止出現(xiàn)JS修 改DOM樹(shù)闲坎,需要重新構(gòu)建DOM樹(shù)的情況疫粥,
所以 就會(huì)阻塞其他的下載和呈現(xiàn)。
(1)Reflow(回流):瀏覽器要花時(shí)間去渲染腰懂,當(dāng)它發(fā)現(xiàn)了某個(gè)部分發(fā)生了變化影響了布局梗逮,那就需要倒回去重新渲染。
(2)Repaint(重繪):如果只是改變了某個(gè)元素的背景顏色绣溜,文字顏色等慷彤,不影響元素周圍或內(nèi)部布局的屬性,將只會(huì)引起瀏覽器的repaint怖喻,重畫(huà)某一部分底哗。
Reflow要比Repaint更花費(fèi)時(shí)間