瀏覽器DOM渲染解析過程總結

瀏覽器DOM渲染解析過程總結

1、瀏覽器的主要組件(以下圖所示)

在這裏插入圖片描述

備註:Interface表示人機交互界面。javascript

  1. 用戶界面(User Interface):是指瀏覽器功能模塊的UI佈局。例如:地址欄、前進/後臺按鈕、收藏夾等。不一樣瀏覽器他們的功能模塊的UI佈局是不同的。
  2. 瀏覽器引擎(Browser engine):在UI界面和渲染引擎之間傳遞指令;同時操做數據存儲(Data Persistence)對數據持久化處理;
  3. 渲染引擎(Rendering engine):主要負責將請求的佈局文件、樣式文件進行解析渲染呈現出Web頁面;
  4. 網絡(Networking):進行HTTP請求調用;
  5. JS解釋器(JavaScript Interpreter):主要負責解析並執行JavaScript語言;
  6. 用戶界面後端(UI Backend):用於繪製基本的窗口小部件,好比組合框和窗口。其公開了與平臺無關的通用接口,而在底層使用操做系統的用戶界面方法。
  7. 數據存儲(Data Persistence):負責將數據在瀏覽器中進行持久化存儲。例如:cookie、session、localStorage、indexDB等存儲功能。

重點理解:Rendering engine(渲染引擎)、NetWorking(網絡)、JavaScript Interpreter(JS引擎)、Data Persistence(數據存儲)html

2、瀏覽器生成DOM解析頁面過程(以下圖所示)

在這裏插入圖片描述
第一步:將載入的HTML文件解析成DOM樹(DOM Tree),而且將各個標記標識解析成DOM樹的各個節點;在解析HTML的同時會將CSS樣式解析成CSS規則(CSS Rules)。

第二步:將解析成的DOM樹和CSS規則進行關聯生成渲染樹(Render Tree)。html5

第三步:進入佈局階段,爲DOM樹的每一個節點分配在屏幕上出現的確切座標(這一階段仍是渲染樹)java

第四步:進入繪製階段,在這裏渲染引擎的工做就結束了,接下來就給用戶界面後端(UI Backend)對渲染樹的每一個節點進行繪製,呈現出頁面效果。chrome

說明:爲了提升頁面呈現速度,渲染引擎採用的是漸進式渲染,也就是在邊解析、邊渲染的模式下進行工做的,它沒必要等着整個HTML解析完成再渲染。後端

疑問總結?

問: 爲何有些網頁打開時過了幾秒纔有樣式出現?
答:這個問題跟渲染引擎無關,主要因爲請求CSS樣式文件時網絡延時形成。
複製代碼

3、不一樣內核瀏覽器的DOM解析的差別性(以下圖所示)

在這裏插入圖片描述

  • Webkit內核的瀏覽器:chrome、Safari
  • Gecko內核的瀏覽器:Firefox

從上圖可知,Webkit和Gecko內核的渲染流程和機制總體上是一致的,它們的差別性總結:瀏覽器

  1. 術語上不一致,Webkit內核中DOM Tree(DOM樹)、Render Tree(渲染樹)、Layout(佈局),Gecko內核中Content Model(內容模型)、Frame Tree(框架樹)、Reflow(迴流)。
  2. 在將HTML解析後Gecko比Webkit多一層,稱爲Content Sink(內容槽)。

4、JS操做DOM的性能優化方案

衆所周知,直接用JS操做DOM是很浪費性能的。由於每次經過JS操做(訪問/新增/刪除/更新)DOM都會致使DOM Tree(DOM樹)從新佈局/迴流、繪製(簡稱重排、重繪過程)。緩存

重排: 當DOM節點信息發生變化,例如位置改變,DOM節點大小改變,都會對該DOM從新計算,並進行佈局/迴流操做(不一樣瀏覽器術語不同);性能優化

****怎樣會致使重排?****
1. 縮放瀏覽器窗口;
2. 改變頁面中DOM節點大小或位置;
3. 經過innerHTML/innerText修改DOM節點上的字體信息。注意:文本也屬於DOM節點之一(文本節點);
4. 經過JS的dom中style屬性來改變DOM節點的樣式;
5. 經過JS對DOM節點進行操做(訪問/新增/刪除/更新);
6. HTML頁面首次呈現;
複製代碼

重繪: 當DOM節點信息不發生變化時,只改變了DOM節點的外貌樣式時(不改變DOM節點的位置和大小,只改變字體顏色或背景色等)。會對該DOM進行從新繪製。注意有重排一定會有重繪,有重繪不必定有重排;bash

  1. 經過變量緩存DOM對象引用,以此減小對DOM的直接操做;
//基本方式
for(var i=0;i<100;i++){
    var dom=document.getElementById("xxx");
    dom.innerHTML=dom.innerHTML+i;
}
//變量緩存DOM引用
var dom=document.getElementById("xxx");
for(var i=0;i<100;i++){
    dom.innerHTML=dom.innerHTML+i;
}
複製代碼
  1. 使用createDocumentFragment()方法建立DOM碎片容器;
//基本方式
var dom=document.getElementById("xxx");
for(var i=0;i<100;i++){
    var cre_dom=document.createElement("xxx");
    dom.appendChild(cre_dom);
}
//使用createDocumentFragment
var dom=document.getElementById("xxx");
var cre_frag=document.createDocumentFragment();
for(var i=0;i<100;i++){
    var cre_dom=document.createElement("xxx");
    cre_frag.appendChild(cre_dom);
}
dom.appendChild(cre_frag);
複製代碼
  1. 採用性能更優的querySelectAll()訪問DOM節點;
  2. 使用CSS3動畫機制,開啓硬件加速,將渲染計算交給GPU;

參考文章:www.html5rocks.com/en/tutorial…

相關文章
相關標籤/搜索