鏈接:https://www.zhihu.com/question/20117417/answer/223591
從上面這個圖中,我們可以看到那么幾個事:
1)瀏覽器會解析三個東西:
一個是HTML/SVG/XHTML,事實上,Webkit有三個C++的類對應這三類文檔。解析這三種文件會產生一個DOM Tree。
CSS,解析CSS會產生CSS規則樹。
Javascript,腳本,主要是通過DOM API和CSSOM API來操作DOM Tree和CSS Rule Tree.
2)解析完成后,瀏覽器引擎會通過DOM Tree 和 CSS Rule Tree 來構造 Rendering Tree。注意:
Rendering Tree 渲染樹並不等同於DOM樹,因為一些像Header或display:none的東西就沒必要放在渲染樹中了。
CSS 的 Rule Tree主要是為了完成匹配並把CSS Rule附加上Rendering Tree上的每個Element。也就是DOM結點。也就是所謂的Frame。
然后,計算每個Frame(也就是每個Element)的位置,這又叫layout和reflow過程。
3)最后通過調用操作系統Native GUI的API繪制。
DOM解析
HTML的DOM Tree解析如下:
<html>
<html>
<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會解析成這樣:

下面是另一個有SVG標簽的情況。

CSS解析
CSS的解析大概是下面這個樣子(下面主要說的是Gecko也就是Firefox的玩法),假設我們有下面的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條規則出現了兩次,一次是獨立的,一次是在規則3的子結點。所以,我們可以知道,建立CSS Rule Tree是需要比照着DOM Tree來的。CSS匹配DOM Tree主要是從右到左解析CSS的Selector,好多人以為這個事會比較快,其實並不一定。關鍵還看我們的CSS的Selector怎么寫了。
注意:CSS匹配HTML元素是一個相當復雜和有性能問題的事情。所以,你就會在N多地方看到很多人都告訴你,DOM樹要小,CSS盡量用id和class,千萬不要過渡層疊下去,……
通過這兩個樹,我們可以得到一個叫Style Context Tree,也就是下面這樣(把CSS Rule結點Attach到DOM Tree上):

所以,Firefox基本上來說是通過CSS 解析 生成 CSS Rule Tree,然后,通過比對DOM生成Style Context Tree,然后Firefox通過把Style Context Tree和其Render Tree(Frame Tree)關聯上,就完成了。注意:Render Tree會把一些不可見的結點去除掉。而Firefox中所謂的Frame就是一個DOM結點,不要被其名字所迷惑了。

注:Webkit不像Firefox要用兩個樹來干這個,Webkit也有Style對象,它直接把這個Style對象存在了相應的DOM結點上了。
渲染
渲染的流程基本上如下(黃色的四個步驟):
計算CSS樣式
構建Render Tree
Layout – 定位坐標和大小,是否換行,各種position, overflow, z-index屬性 ……
正式開畫

CSS森林(CSS Forest): 瀏覽器工作原理淺析

加載:根據請求的URL進行域名解析,向服務器發起請求,接收文件(HTML、JS、CSS、圖象等)。
解析:對加載到的資源(HTML、JS、CSS等)進行語法解析,建議相應的內部數據結構(比如HTML的DOM樹,JS的(對象)屬性表,CSS的樣式規則等等)
渲染:構建渲染樹,對各個元素進行位置計算、樣式計算等等,然后根據渲染樹對頁面進行渲染(可以理解為“畫”元素)
這幾個過程不是完全孤立的,會有交叉,比如HTML加載后就會進行解析,然后拉取HTML中指定的CSS、JS等。