
從上面這個圖中,我們可以看到那么幾個事:
1)瀏覽器會解析三個東西:
一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文檔。解析這三種文件會產(chǎn)生一個DOM Tree。
CSS,解析CSS會產(chǎn)生CSS規(guī)則樹。
Javascript,腳本,主要是通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree.
2)解析完成后,瀏覽器引擎會通過DOM Tree 和 CSS Rule Tree 來構(gòu)造 Rendering Tree。注意:
Rendering Tree 渲染樹并不等同于DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。
CSS 的 Rule Tree主要是為了完成匹配并把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結(jié)點。也就是所謂的Frame。
然后,計算每個Frame(也就是每個Element)的位置,這又叫l(wèi)ayout和reflow過程。
3)最后通過調(diào)用操作系統(tǒng)Native GUI的API繪制。
DOM解析
HTML的DOM Tree解析如下:
<body>
<head>
<title>Web page parsing</title>
</head>
<body>
<div>
<h1 >Web page parsing</h1>
<p>This is an example Web page.</p>
</div>
</body>
</html>```
上面這段HTML會解析成這樣:

```<doc>
<title>A few quotes</title>
<para>
Franklin said that <quote>"A penny saved is a penny earned."</quote>
</para>
<para>
FDR said <quote>"We have nothing to fear but <span>fear itself.</span>"</quote>
</para>
</doc>```
于是DOM Tree是這個樣子:

然后我們的CSS文檔是這樣的:
`````` /* rule 1 */ doc { display: block; text-indent: 1em; }
/* rule 2 */ title { display: block; font-size: 3em; }
/* rule 3 */ para { display: block; }
/* rule 4 */ [class="emph"] { font-style: italic; }
于是我們的CSS Rule Tree會是這個樣子:

注意,圖中的第4條規(guī)則出現(xiàn)了兩次,一次是獨立的,一次是在規(guī)則3的子結(jié)點。所以,我們可以知道,建立CSS Rule Tree是需要比照著DOM Tree來的。CSS匹配DOM Tree主要是從右到左解析CSS的Selector,好多人以為這個事會比較快,其實并不一定。關(guān)鍵還看我們的CSS的Selector怎么寫了。
注意:CSS匹配HTML元素是一個相當復雜和有性能問題的事情。所以,你就會在N多地方看到很多人都告訴你,DOM樹要小,CSS盡量用id和class,千萬不要過渡層疊下去,……
通過這兩個樹,我們可以得到一個叫Style Context Tree,也就是下面這樣(把CSS Rule結(jié)點Attach到DOM Tree上):

渲染
渲染的流程基本上如下(黃色的四個步驟):
計算CSS樣式
構(gòu)建Render Tree
Layout – 定位坐標和大小,是否換行,各種position, overflow, z-index屬性 ……
正式開畫

注意:上圖流程中有很多連接線,這表示了Javascript動態(tài)修改了DOM屬性或是CSS屬會導致重新Layout,有些改變不會,就是那些指到天上的箭頭,比如,修改后的CSS rule沒有被匹配到,等。
這里重要要說兩個概念,一個是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,比如一個文本字符串必需被包裝起來。
幾個工具
Chrome下,Google的SpeedTracer是個非常強悍的工作讓你看看你的瀏覽渲染的成本有多大。其實Safari和Chrome都可以使用開發(fā)者工具里的一個Timeline的東東。
Firefox下這個基于Firebug的叫Firebug Paint Events的插件也不錯。
IE下你可以用一個叫dynaTrace的IE擴展。