基於Webkit的瀏覽器關鍵渲染路徑介紹

關鍵渲染路徑概念

瀏覽器是如何將HTML、JS、CSS、image等資源渲染成可視化的頁面的呢?本文簡單介紹一下渲染過程當中涉及到的關鍵步驟。css

該過程分爲四步:模型對象的構建、渲染樹構建、佈局、繪製。html

 

1.模型對象的構建

瀏覽器獲取到HTML、CSS文件後,須要對其進行解析,抽象成DOM和CSSOM對象,而後提供相應的JS API,方便開發者進行交互邏輯開發。前端

HTML文件字節轉變成DOM的過程以下圖所示:web

主要經歷字符編碼—》令牌提取標籤—》詞法分析轉變成DOM對象—》依照標籤的嵌套關係構建成DOM樹;chrome

 

 

CSS文件字節轉變成CSSOM的過程與HTML轉DOM相似,區別就是按照規則通用性創建樹形關係。瀏覽器

2.渲染樹的構建

所謂渲染樹,就是將DOM樹和CSSOM樹合併,獲得每一個可見元素的內容和顯示樣式。緩存

 

Tips:性能優化

(1)渲染樹並不是顯示全部元素,而只是佔據空間元素,如display: none的元素不在渲染樹中,而visibility: hidden的在渲染樹中;網絡

(2)渲染樹包含的內容只是元素的內容及其樣式信息,在不一樣視口(viewport,也就是瀏覽器的屏幕畫布)下實際展現肯能會有差異;dom

(3)渲染樹構建後,Webkit還會繼續構建渲染層(RenderLayer),這是爲了簡化渲染邏輯,同時方便開發者查看網頁層次。

3.佈局

通過前兩步的操做,咱們知道了元素的內容和樣式信息,可是實際在不一樣顯示器中的大小和位置如何肯定呢,這就須要進行佈局操做了,有的地方稱爲"自動重排"(reflow)。Webkit依據框模型來計算元素的位置和大小,佈局輸出的是一個"盒模型"對象,該對象包含了每一個元素在視口內的確切位置和尺寸。

 

4.繪製

在佈局結束後,接下來就是繪製,實現柵格化。繪製通常涉及到Paint和Composite Layers。

Paint通常經過圖像上下文來控制,分爲2D和3D繪製上下文。

前文提到了RenderLayer的概念,繪製過程當中,每一個RenderLayer是輸出圖像中的一層,各個層根據深度信息組合成一張圖像,這個組合的過程稱爲Composite Layers。

 

關鍵渲染路徑開發相關

介紹完了關鍵渲染路徑的概念,接下來結合chrome dev-tool來看一下實際的狀況,chrome的版本是60.0。

1.代碼

<html>
<head>
    <title>Janky Animation</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="index.css"/>
    <link rel="stylesheet" type="text/css" href="https://ss1.bdstatic.com/
    5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/soutu/css/soutu.css"/>
</head>
<body>
    <img class="proto mover" src="./images/logo-1024px.png"/>
    <div class="controls">
        <button class="add"></button>
        <button class="subtract" disabled></button>
        <button class="stop">Stop</button>
        <button class="optimize">Optimize</button>
        <button class="optimize-fastdom">Optimize By Fastdom</button>
        <a href="https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/"
           target="_blank">
            <button class="optimize">Help</button>
        </a>
    </div>
    <script src="./libs/fastdom.js"></script>
    <script src="index.js"></script>
</body>
</html>

  

2.使用performance調試

爲了不chrome插件的干擾,建議使用【隱身窗口】打開頁面,而後打開dev-tool,選擇Performance進行調試

 

3.main線程的使用狀況

渲染的關鍵路徑主要體如今主線程中,以下圖所示。

圖中的藍色的Parse HTML表示DOM的構建過程,藍色的Parse StyleSheet表明CSSOM的構建過程,黃色的Evaluate Script表示JS的執行過程,紫色的Recalculate Style表示構建Render Tree的過程,紫色的Layout表示佈局過程。

(1)單線程

雖然資源的下載能夠並行,可是資源的解析是單線程的,主要經過Main線程來解析,由下圖所示,ParseHTML被JS的解析阻塞,分紅了三段。線程的使用狀況和代碼中的資源的位置有很大關係,這個下面會介紹。

 

(2)時間線事件

Main線程中的圖中,有一些細線條記錄着一些事件的觸發時間,光標放在上面就能夠查看。事件主要分爲Loading、Scripting、Redering、Painting四大類,具體能夠查看官方介紹。其中Scripting類型中有一種Event類型的事件,以下圖中的Event(DOMCotentLoaded)能夠在JS中被監聽到,經常使用的還有readystatechange、pageshow、pagehide、loaded、webkitvisiblechange等,最近有一個項目中pageshow事件就幫我解決了IOS WKWebview回退頁面緩存不刷新的問題。

  

 

Tips:

(1)HTML文件中JS文件、CSS文件的位置

一般咱們會將css文件放在head標籤中,JS文件放置在body標籤的後面,這是有必定道理的。因爲JS執行的過程當中可能修改DOM和CSS樣式,這也就形成了Evaluate Script的執行會阻塞Parse HTML的過程,若是JS中引用未解析到的DOM程序就會報錯;若是script標籤以前有引入css文件,Evaluate Script會等到Parse Stylesheet過程結束後再執行。

因此將CSS文件放置在頭部,提早下載並解析;將JS文件放在尾部,讓JS儘量的訪問到全部的DOM,避免報錯。

(2)優化渲染路徑的重要性

前端性能優化主要分爲網絡請求和代碼層面兩種。網絡請求上的方法是壓縮合並、按需加載、緩存等;代碼層面則就是要優化渲染路徑,畢竟單線程要在模型對象構建、渲染樹構建、佈局、渲染之間切換,以下圖所示。

優化渲染路徑對於頁面性能相當重要,接下來會寫幾篇文章針對不一樣階段給出優化方法,敬請期待。

相關文章
相關標籤/搜索