簡述瀏覽器的渲染機制

渲染圖

引用文章
瀏覽器能夠?qū)σ韵挛募M行解析,HTML,SVG和XHTML;解析生成DOM樹;javascript腳本文件會通過DOM API 和CSSOM API操控DOM Tree;CSS文件解析生成CSS Rule Tree。
解析完成后瀏覽器引擎會根據(jù)生成的DOM樹和CSS規(guī)則樹構(gòu)建渲染樹;但渲染樹不一定等同于DOM樹因為元素中display:none或者其他的一些標簽不會放在渲染樹中進行渲染。
CSS規(guī)則樹會匹配到渲染樹中的每個元素(DOM節(jié)點),并給它們加上CSS Rule。然后計算每個元素的位置,這個過程叫做回流(reflow)。最后通過調(diào)用操作系統(tǒng)Native GUI的API繪制。

DOM樹的解析過程(Firefox)

<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>

上述代碼的DOM樹會被解析成這樣:


DOM樹

CSS規(guī)則樹的解析過程(Firefox)

<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樹

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規(guī)則樹

CSS規(guī)則樹圖中rule4出現(xiàn)了2次,一次是獨立的,另一次在規(guī)則3的子節(jié)點,建立CSS規(guī)則樹是按照DOM樹的結(jié)構(gòu)來建立的。PS(CSS匹配DOM樹是一個非常耗性能和復雜的事情所以DOM樹要小,CSS盡量用id和class,不要過度層疊下去)
根據(jù)DOM樹和CSS規(guī)則樹匹配構(gòu)造一個Style Context Tree;然后關(guān)聯(lián)Style Context Tree和渲染樹。
Style Context Tree

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

reflow和repaint

*(為什么不能用CSS通配符 ,CSS選擇器層疊為什么不能超過三層,CSS為什么盡量使用類選擇器,書寫HTML為什么少使用table,為什么結(jié)構(gòu)要盡量簡單-DOM樹要小….)
Reflow:對于DOM結(jié)構(gòu)中的各個元素都有自己的盒子(模型),這些都需要瀏覽器根據(jù)各種樣式(瀏覽器的、開發(fā)人員定義的等)來計算并根據(jù)計算結(jié)果將元素放到它該出現(xiàn)的位置,這個過程稱之為reflow。
Repaint:當各種盒子的位置、大小以及其他屬性,例如顏色、字體大小等都確定下來后,瀏覽器于是便把這些元素都按照各自的特性繪制了一遍,于是頁面的內(nèi)容出現(xiàn)了,這個過程稱之為 repaint。
注意:回流必將引起重繪,而重繪不一定會引起回流
Reflow的成本要比Repaint大得多;DOM樹每個節(jié)點都有一個Reflow方法,一個節(jié)點的Reflow方法有可能觸及父節(jié)點或者其他節(jié)點的Reflow。
增刪改DOM節(jié)點,移動DOM,做動畫,修改CSS樣式滾動頁面,修改默認字體等等都會觸發(fā)Reflow或Repaint。減少Reflow和Repaint的一些方法:

  1. 盡量預先定義好CSS的類,然后去修改DOM的className;
  2. 不要把DOM結(jié)點的屬性值放在一個循環(huán)里當成循環(huán)里的變量;
  3. 為動畫的HTML元件使用fixed或absoult的position,那么修改它們的CSS是不會reflow的;
  4. 盡可能的修改層級比較低的DOM。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容