一、渲染引擎
渲染引擎的職責是……渲染,也就是把請求的內容顯示到瀏覽器屏幕上。
默認情況下渲染引擎可以顯示HTML,XML文檔以及圖片。 通過插件(瀏覽器擴展)它可以顯示其它類型文檔。

二、各種渲染引擎
我們提到的Firefox, Safari兩種瀏覽器構建於兩種渲染引擎之上:
Firefox使用Gecko —— Mozilla自家的渲染引擎;Safari 和 Chrome 都使用 Webkit。

最終決定瀏覽器表現出來的頁面效果的差異是:渲染引擎 Rendering Engine(也叫做排版引擎),也就是我們通常所説的“瀏覽器內核”,負責解析網頁語法(如HTML、JavaScript)並渲染、展示網頁。相同的代碼在不同的瀏覽器呈現出來的效果不一樣,那麼就很有可能是不同的瀏覽器內核導致的。

三、主要流程

渲染引擎開始於從網絡層獲取請求內容,一般是不超過8K的數據塊。接下來就是渲染引擎的基本工作流程:

fstorm渲染器材質_渲染引擎


渲染引擎的基本工作流程(解析HTML構建DOM樹,渲染樹構建,渲染樹佈局,繪製渲染樹)。

1、解析HTML以重建DOM樹(Parsing HTML to construct the DOM tree ):渲染引擎開始解析HTML文檔,轉換樹中的標籤到DOM節點,它被稱為“內容樹”。

2、構建渲染樹(Render tree construction):解析CSS(包括外部CSS文件和樣式元素),根據CSS選擇器計算出節點的樣式,創建另一個樹 —- 渲染樹。

3、佈局渲染樹(Layout of the render tree): 從根節點遞歸調用,計算每一個元素的大小、位置等,給每個節點所應該出現在屏幕上的精確座標。

4、繪製渲染樹(Painting the render tree) : 遍歷渲染樹,每個節點將使用UI後端層來繪製。


一定要理解這是一個緩慢的過程,為了更好的用户體驗,渲染引擎會嘗試儘快的把內容顯示出來。它不會等到所有HTML都被解析完才創建並佈局渲染樹。它會 在處理後續內容的同時把處理過的局部內容先展示出來。

四、主要流程示例

圖 2:Webkit主要流程

fstorm渲染器材質_fstorm渲染器材質_02

圖 3:Mozilla的Gecko渲染引擎主要流程(3.6)

fstorm渲染器材質_渲染引擎_03

 

從圖2和圖3中可以看出,儘管Webkit與Gecko使用略微不同的術語,這個過程還是基本相同的。
Gecko裏把格式化好的可視元素稱做“幀樹”(Frame tree)。每個元素就是一個幀(frame)。
Webkit則使用”渲染樹”這個術語,渲染樹由”渲染對象”組成。
Webkit裏使用”layout”表示元素的佈局,Gecko則稱為”Reflow”。
Webkit使用”Attachment”來連接DOM節點與可視化信息以構建渲染樹。
一個非語義上的小差別是Gecko在HTML與DOM樹之間有一個附加的層 ,稱作”content sink”,是創建DOM對象的工廠。

主要的流程就是:構建一個dom樹,頁面要顯示的各元素都會創建到這個dom樹當中,每當一個新元素加入到這個dom樹當中,瀏覽器便會通過css引擎查遍css樣式表,找到符合該元素的樣式規則應用到這個元素上。

五、瀏覽器對CSS的匹配原理

瀏覽器CSS匹配是從右到左進行查找。比如之前説的DIV#divBoxpspan.red{color:red;},瀏 覽器 的查找順序如下:先查找html中所有class=’red’的span元素,找到後,再查找其父輩元素中是否有p元素,再判斷p的父元素中是否有id為 divBox的div元素,如果都存在則CSS匹配上。

瀏覽器從右到左進行查找的好處是為了儘早過濾掉一些無關的樣式規則和元素。firefox稱這種查 找方式為keyselector(關鍵字查詢),所謂的關鍵字就是樣式規則中最後(最右邊)的規則,上面的key就是span.red。

 

六、優化你的CSS
1.css 命名 、書寫規範。
好的代碼看上去就很整齊 很有條理性這樣方便日後的維護和管理。
2.避免使用通配規則。
*{}  計算次數驚人!只對需要用到的元素進行選擇。
3.css優先級。
選擇器權重:內聯樣式:1000,id選擇器:100, class選擇器:10,標籤選擇器:1 。
上一篇有總結。CSS選擇器的權重與優先規則?4.少用濾鏡,少用hack,少用position:absolute;。
5.儘量少的去對標籤進行選擇,而是用class。
如:#nav li{},可以為li加上nav_item的類名,如下選擇.nav_item{}。
6.不要去用標籤限定ID或者類選擇符
如:ul#nav,應該簡化為#nav。
如:div.box { color: #f00; }; 直接 可以 用類名, .box { color:#f00;}  這樣瀏覽器找到這個class後 就不用再匹配是否存在div標籤.從而提高了渲染效率。當然同一級的 有不同的樣式可以這樣寫,但是不建議這樣。
7.儘量少的去使用後代選擇器,降低選擇器的權重值,css的層級關係不要太深 用class直接代替多餘的層級元素。
後代選擇器的開銷是最高的,儘量將選擇器的深度降到最低,最高不要超過三層,更多的使用類來關聯每一個標籤元素。
例如 .box .box-con .box-list li { line-height: 24px; } 這麼長。。。增加代碼量減小開發效率。剛也説了,css渲染是從上到下,從右到左的
所以直接這樣寫就可以了.box-list li { line-height: 24px; };
8.使用簡寫樣式。
例如margin: 10px; 瀏覽器會解釋為上下左右各有10px的外補丁。margin: 0 10px 瀏覽器解析為 左右有10px的外補丁。
9.平鋪背景圖片不要過小,影響渲染速率。
10.float使用要謹慎。
11.不要放空的class。
別放空的的class或沒有的class在html代碼中,這樣無意義。
12.多用繼承屬性。
考慮繼承 瞭解哪些屬性是可以通過繼承而來的,然後避免對這些屬性重複指定規則。

<style>
  a:link,a:visited{color:#0000FF}
  a:hover,a:active{color:#FF0000}
  #zishu a:link,#zishu a:visited{ font-weight:bold}
  #zishu a:hover,#zishu a:active{ font-style: italic;}
</style>
<div><a href="#">test</a><div>
<div id="zishu"><a href="#">jb51.net</a></div>

13.合理化佈局(模塊化佈局)。
可以把樣式劃分為 基類 和擴展類 ;模塊化佈局 :
模塊基本相同的樣式寫在 基類裏,不同的在重新用class來定義稱為擴展類 。
14.在css渲染效率中id和class的效率是基本相當的。
class在第一次載入中被緩存,在層疊中會有更加好的效果,在根部元素採用id會具有更加好(id有微妙的速度優勢)。