CSSOM樹和DOM樹連接在一起形成一個render tree,渲染樹用來計算可見元素的布局並且作為將像素渲染到屏幕上的過程的輸入。
- DOM樹和CSSOM樹連接在一起形成render tree .
- render tree只包含了用於渲染頁面的節點
- 布局計算了每一個對象的准確的位置以及大小
- 繪畫是最后一步,繪畫要求利用render tree來將像素顯示到屏幕上
第一步是結合DOM樹和CSSOM樹形成“render tree”,渲染樹用來描述所有可見的DOM內容,並且將CSSOM樣式信息附加到節點上。

為了形成渲染樹,瀏覽器大致做的事情有:
- 從DOM樹根節點開始,遍歷每一個可見的節點
- 一些節點是完全不可見的(比如 script標簽,meta標簽等),這些節點會被忽略,因為他們不會影響渲染的輸出
- 一些節點是通過CSS樣式隱藏了,這些節點同樣被忽略——例如上例中的span節點在render tree中被忽略,因為span樣式是display:none;
- 對每一個可見的節點,找到合適的匹配的CSSOM規則,並且應用樣式
- 顯示可見節點(節點包括內容和被計算的樣式)
記住
- 記住“visibility:hidden”和“display:none”之間的不同,“visibility:hidden”將元素設置為不可見,但是同樣在布局上占領一定空間(例如,它會被渲染成為空盒子),但是“display:none”的元素是將節點從整個render tree中移除,所以不是布局中的一部分 。
最后輸出的是一個render包括了屏幕上可見內容的樣式信息和內容信息。
我們知道了哪些元素應該被顯示以及元素的樣式,但是我們還沒有計算元素在設備中的確切的位置和大小——這是“布局”階段,同樣也被叫做“reflow”。
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Critial Path: Hello world!</title> </head> <body> <div style="width: 50%"> <div style="width: 50%">Hello world!</div> </div> </body> </html>
上面的頁面展示了兩個div:第一個div是整個視圖的一半,第二個div是父親寬度的一半——也就是說是整個視圖的25%。

布局的輸出是“盒子模型”,並且將相對定位轉化成屏幕上的絕對像素。
最后,我們只差將render tree上的所有節點轉化成屏幕上的確切像素——這個步驟通常被稱為“painting”或者“rasterizing”。
每個步驟都要花費一些時間,谷歌瀏覽器開封工具為我們描述了一些步驟所花費的時間:

- 構造render tree和計算位置以及大小信息被捕捉在時間軸上的“Layout”時間中
- 一旦布局完成,瀏覽器計算"Paint Setup"和“Paint”事件用來描述render tree轉化成屏幕上世紀像素的時間。
顯示構造render tree以及布局和paint的時間受到頁面的大小,被應用的樣式和正在運行的設備影響。
頁面越大,瀏覽器將要做更多工作;樣式越復雜,painting階段所花費的時間也越多。
但是,我們的頁面完成了!WOOOO!

讓我們快速的瀏覽下瀏覽器所做的事情:
- 處理HTML標簽建立DOM樹
- 處理CSS標簽建立CSSOM樹
- 連接CSSOM樹和DOM樹形成一個render樹
- 在render樹上運行布局來計算每個節點的形狀
- 在屏幕上畫每一個節點
雖然我們的頁面很簡單,但是它進行了大量的工作!下一章我們討論怎樣對渲染進行優化。
