前端設(shè)計工程師重在設(shè)計網(wǎng)站,只有了解了瀏覽器的渲染方式,才能在發(fā)現(xiàn)問題的同時更好的定位,便于網(wǎng)站的優(yōu)化。
瀏覽器工作的大致流程
如圖:

根據(jù)上圖,簡單的分析一下:
1、瀏覽器會解析三個東西:
a. HTML/SVG/XHTML,Webkit有三個C++的類對應(yīng)這三類文檔,解析這三種文件會產(chǎn)生一個DOM Tree。
b. CSS 解析CSS會產(chǎn)生CSS Rule Tree。
c. JavaScript,腳本,主要是通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree。
2、解析完成后,瀏覽器引擎會通過DOM Tree 和 CSS Rule Tree 來構(gòu)造 Rendering Tree。
a. Rendering Tree 渲染樹并不等同于DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。
b. CSS 的 Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結(jié)點。也就是所謂的Frame。
c. 然后,計算每個Frame(也就是每個Element)的位置,這又叫l(wèi)ayout和reflow過程。
3、最后通過調(diào)用操作系統(tǒng)Native GUI的API繪制。
渲染
流程:
- 計算CSS樣式
- 構(gòu)建Render Tree
- Layout-定位坐標和大小,是否換行,或者其他屬性
- 繪畫
Reflow和Repaint
當(dāng)JS修改了CSS屬性,或者手動修改的CSS屬性導(dǎo)致layout時,涉及到兩個概念,Reflow和Repaint。
Repaint:屏幕的一部分要重畫,比如某個CSS的背景色變了。但是元素的幾何尺寸沒有變。
Reflow:意味著元件的幾何尺寸變了,我們需要重新驗證并計算Render Tree。是Render Tree的一部分或全部發(fā)生了變化。這就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的幾何尺寸發(fā)生了變化,需要重新布局,也就叫reflow)reflow 會從<html>這個root frame開始遞歸往下,依次計算所有的結(jié)點幾何尺寸和位置,在reflow過程中,可能會增加一些frame,比如一個文本字符串必需被包裝起來。
顯然,Reflow的成本比Repaint的成本要高得多。下面列舉一些高成本的動作:
a. 當(dāng)增加、刪除、修改DOM結(jié)點時,會導(dǎo)致Reflow或Repaint
b. 當(dāng)移動DOM的位置,或是搞個動畫的時候。
c. 當(dāng)修改CSS樣式的時候。
d. 當(dāng)Resize窗口的時候(移動端沒有這個問題),或是滾動的時候。
e. 當(dāng)修改網(wǎng)頁的默認字體時。
基本上,Reflow的原因如下:
a. Initial。網(wǎng)頁初始化的時候。
b. Incremental。一些Javascript在操作DOM Tree時。
c. Resize。其些元件的尺寸變了。
d. StyleChange。如果CSS的屬性發(fā)生變化了。
e. Dirty。幾個Incremental的reflow發(fā)生在同一個frame的子樹上。
盡量減少Reflow的操作:
a. 不要一條一條地修改DOM的樣式。與其這樣,還不如預(yù)先定義好css的class,然后修改DOM的className。
b. 把DOM離線后修改。
c. 不要把DOM結(jié)點的屬性值放在一個循環(huán)里當(dāng)成循環(huán)里的變量。
d. 盡可能的修改層級比較低的DOM。
e. 為動畫的HTML元件使用fixed或absoult的position
f. 千萬不要使用table布局。