渲染機制概述
解析 HTML 標簽, 構(gòu)建 DOM 樹
解析 CSS 標簽, 構(gòu)建 CSSOM 樹
把 DOM 和 CSSOM 組合成 渲染樹 (render tree)
在渲染樹的基礎上進行布局, 計算每個節(jié)點的幾何結(jié)構(gòu)
把每個節(jié)點繪制到屏幕上 (painting)
過程分析
拿到HTML代碼后,瀏覽器開始解析HTML代碼構(gòu)建DOM樹。
這個過程是根據(jù)代碼自上而下的。
當解析到style 或者 link外鏈css時鼻忠,會阻塞停止HTML的解析,DOM樹的構(gòu)建。
等請求下載解析css并且CSSOM構(gòu)建完畢時粘捎,才會繼續(xù)解析后面的HTML代碼。
當繼續(xù)解析到script 或者 外鏈js腳本時危彩,會阻塞停止HTML的解析攒磨,DOM樹的構(gòu)建。
注意:
然后繼續(xù)解析HTML汤徽。每解析完一個DOM 就結(jié)合CSSOM 繪制好(不同瀏覽器處理方式不同)娩缰。
遇到圖片src就建立請求獲取圖片,但是不等待繼續(xù)解析后面的HTML(異步并行過程)谒府,等到圖片獲取到以后再回頭Reflow拼坎,如果沒有影響布局則Repaint。
(1)Reflow(回流):瀏覽器要花時間去渲染完疫,當它發(fā)現(xiàn)了某個部分發(fā)生了變化影響了布局泰鸡,那就需要倒回去重新渲染。
(2)Repaint(重繪):如果只是改變了某個元素的背景顏色壳鹤,文字顏色等盛龄,不影響元素周圍或內(nèi)部布局的屬性,將只會引起瀏覽器的repaint芳誓,重畫某一部分余舶。
等到所有標簽解析完畢則渲染結(jié)束。
提高網(wǎng)頁加載速度 和避免異常情況的處理方法
CSS
為了提高網(wǎng)頁加載速度锹淌,對于首頁無關的樣式匿值,需要使用適當?shù)姆绞奖苊馄渥枞醮武秩荆?/strong>
- 使用media=print媒體查詢,雖然加載樣式表葛圃,但只針對打印時才應用該樣式千扔,不會阻塞初次渲染。
- 通過DOMAPI引入CSS库正,可以避免阻塞曲楚。
- CSS中<link rel="preload" href="index_print.css" as="style" onload="this.rel='stylesheet'">。
另:css選擇器的機制是從右往左褥符,所以應避免過多的選擇器嵌套
JS
JS腳本執(zhí)行會阻塞HTML Parser龙誊;
CSS解析會阻塞JS腳本執(zhí)行:js可能會讀、寫CSSOM
雖然JS會阻塞HTML Parser解析喷楣;但是瀏覽器的資源異步加載機制Preload會異步加載head標簽內(nèi)的資源
非關鍵JS資源解析阻塞的優(yōu)化方案:
- 將JS資源文件放在文檔底部趟大,延遲JS的執(zhí)行(但是存在必須解析完HTML才能加載JS資源鹤树,相較于head標簽中加載會慢)
- 使用defer延遲腳本執(zhí)行:scipt標簽的defer屬性,腳本會在HTML文檔解析完畢后再開始執(zhí)行逊朽;被defer的腳本在執(zhí)行時嚴格按照HTML文檔中出現(xiàn)的順序執(zhí)行---優(yōu)勢可以提早加載JS資源罕伯,但是解析完HTML再執(zhí)行
- 使用async異步執(zhí)行腳本:
-當script標簽有async屬性時,腳本執(zhí)行不會阻塞HTML Parser叽讳,只要腳本加載完畢便開始執(zhí)行
被async的腳本追他,不會嚴格按照在HTML文檔中的順序執(zhí)行
async適用于無依賴的外部獨立資源(注意不要錯誤操作狀態(tài))
font
img
圖片資源的加載不會阻塞渲染,但是最好在HTML標簽中設置圖片的高度和寬度岛蚤,可以在Layout時留出圖片渲染的空間邑狸,避免頁面的抖動