原文:Rendering: repaint, reflow/relayout, restyle
標題包含5個R開頭的單詞,很酷不是嗎?讓我們討論下頁面渲染--頁面的生命週期2.0的一個階段,有的時候是在發生在下載組件的過程中。
給定大量的HTML,CSS也可能有JavaScript,瀏覽器是如何在屏幕上展現頁面的呢?
渲染的過程
不同的瀏覽器的渲染原理不一樣,但是一旦瀏覽器將你頁面的代碼下載下來後,下面的圖表給出了大致的原理,或多或少是跨瀏覽器一致的。
1、瀏覽器解析HTML源代碼(各個標籤),並且構造一棵DOM樹 -- 一個數據表示,每一個HTML標籤都在裏面有一個對應的節點,標籤間的文本塊也都有一個對應的文本節點表示。DOM樹中的根節點是documentElement(HTML標籤)。
2、然後瀏覽器開始解析CSS代碼,搞清楚CSS代碼裏給定的各種可能的Hack,並果斷忽略大量的-moz,-webkit前綴和其他瀏覽器並不懂的擴展。樣式信息渲染的先後順序爲:
在用戶代理裏面(瀏覽器默認)的基本規則;然後是可能的用戶自己的樣式,作者(在作者頁面)的樣式 -- 外部的,導入的,行內的,最後是嵌入在HTML標籤的style屬性裏的樣式代碼。
3、接下來是很有意思的部分 -- 構造渲染樹。渲染樹在一定程度上和DOM樹比較類似,但和DOM樹並不完全匹配。渲染樹知道DOM的樣式,因此如果你用display:none;來隱藏了一個元素,它就不會出現在渲染樹中。類似的,像其他可見元素也不在渲染樹中,比如head以及head內的所有元素。另一方面,在渲染樹中有的元素被多於一個的節點表示 -- 像文本節點,在<p>元素裏的每一行文本都需要一個渲染節點來表示。一個渲染樹中的節點被稱爲一個結構,或者一個盒子(在CSS盒子中,依據的是盒模型)。每一個這些節點都有對應的CSS盒屬性 -- width, height, border, margin等等。
4、一旦渲染樹被構造完成,瀏覽器就可以在頁面上去繪製渲染樹。
森林與樹
<html>
<head>
<title>Beautiful page</title>
</head>
<body>
<p>
Once upon a time there was
a looong paragraph...
</p>
<div style="display: none">
Secret message
</div>
<div><img src="..." /></div>
...
</body>
</html>
代表HTML文檔結構的DOM樹基本上每一個標籤都有一個節點,每一個在節點間的文本都有一個文本節點相對應(簡單起見,我們忽略空格也是文本節點的事實):documentElement (html)
head
title
body
p
[text node]
div
[text node]
div
img
...
渲染樹是DOM樹視覺的一部分。它缺少了一些東西 -- head以及隱藏的div,但是對於多行的文本它有額外的節點(又叫結構,也叫盒子):
root (RenderView)
body
p
line 1
line 2
line 3
...
div
img
...
渲染樹的根節點是包含所有其他元素的結構(或盒子)。你可以把它認爲是瀏覽器窗口內部的部分,因爲這是頁面往外蔓延的禁區。從技術上講,Webkit內核的瀏覽器叫根節點爲RendView,它對應着CSS最初始的包含塊,基本上視口矩形範圍是從頁面的左上角(0,0)到(window.innerWidth, window.innerHeight)。