CSS 繪製時間和網頁轉譯權重

Colt McAnlis
Colt McAnlis

簡介

如果您是喜愛瀏覽器運作方式這類近況的使用者,不久前就已經知道以下幾篇很棒的文章,說明 Chrome 的 GPU 加速轉譯器/複合運算技術。第一篇「Chrome 的加速轉譯功能:圖層模型」說明瞭 Chrome 如何使用圖層概念繪製網頁。如需深入瞭解,請參閱 Chrome 的 GPU 加速合成一文,進一步瞭解 Chrome 如何運用這些圖層,以及 GPU 來轉譯網頁。

思維問題

過去投入大量時間編寫 3D 的軟體光柵化工具後,我們發現有些 CSS 資源在繪製網頁時,成效應該會不一,舉例來說,將小型圖片拖曳到畫面中,是一項完全不同的演算法作業,會在任意形狀上繪製投射陰影。因此問題就變成:「不同的 CSS 屬性對網頁的轉譯權重有何影響?」

我的目標是將一大組 CSS 屬性/值依繪製時間分類,藉此瞭解哪些類型的 CSS 屬性成效較佳。為了做到這點,我編寫了含有觸控式口味和泡泡糖的自動化動作,嘗試為 CSS 繪製時間增加數值顯示時間,運作方式如下:

  • 產生一組個別 HTML 網頁,每個網頁都有單一 DOM 元素,以及附加的 CSS 屬性部分排列方式。
  • 執行幾個自動化指令碼,在每個頁面執行以下動作:
    • 起 Chrome
    • 載入網頁
    • 為頁面產生 Skia 圖片
    • 逐一執行透過 Skia Benchmark 拍攝的 Skia 相片,取得時間記錄
  • 擺脫時間點,數字驚人。(這部分很重要...)

透過這項設定,我們會產生一組 HTML 網頁,其中每個頁面都由不同的 CSS 屬性和值排列組合,例如以下兩個 HTML 檔案:

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

再來,情況複雜多了

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

以下是最後一個範例的變體,我們只變更放射漸層的值:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

接著,系統會將每個網頁載入 Chrome 的「最新」執行個體 (確保在重新載入頁面時,確保時間不會對時間過長),並用 Skia Picture (*.SKP) 評估用於繪製網頁的 Skia 指令。為每個 HTML 檔案產生 SKP 檔案後,我們會執行另一個批次作業,透過 Skia Benchmark 應用程式 (以 Skia 原始碼建構) 推送 *.SKP 檔案,而會傾印顯示該網頁所需的平均時間。

評估資料

現在,我們可以透過基本圖表,呈現一系列 CSS 屬性繪製所需時間。或者,我們也可以按照繪製成效對 CSS 屬性進行堆疊排名。下方是搭配 Chrome 27 Beta 版使用的大型圖表,顯示這個程序的所有時間資料。請注意,隨著 Chrome 的執行速度和速度加快,所有資料都有可能改變。

測試中所有排列項目的時間

每個垂直長條都代表網頁顯示時間採用單一 CSS 屬性組合 (放大 100 倍;這張圖表的真正尺度值為 0,1.56 毫秒)。很多線條都很漂亮,但是這種形式就有些少了。我們得做一些資料探勘找出有用的趨勢。

首先,我們發現部分 CSS 屬性的顯示成本比其他屬性高。舉例來說,在 DOM 元素上繪製投射陰影,牽涉到使用斜坡和其他錯誤物體的多傳遞作業,而不是較容易呈現的透明度。

繪製只有一個 CSS 屬性的元素所需的時間

其次,更值得一提的是,CSS 屬性組合的繪製時間可能會比各自的部分總和更久。就觀察者而言,這個結果有點奇怪,我們預期 A+B = C,而不是 2.2C。例如,新增 box-shadowborder-radius-stroke

測試中所有排列項目的時間

更有趣的是,這不僅是 box-shadow 屬性本身,更是特定的值排列組合例如,下方顯示一組 box-shadow : 50%border-radius 群組的值會變動。

測試中所有排列項目的時間

查看資料後,這項操作需要一段時間。其中有許多奇怪的組合,而我的測試套件雖然無法涵蓋所有組合;目前仍有大量的測試和組合可以產生令人耳目一新的結果

找出網頁的轉譯量

既然能追蹤網頁上每個元素的轉譯時間,開發人員就能開始評估網頁的轉譯量,以及網頁回應速度對網站回應速度的影響。以下提供幾個入門訣竅:

  1. 使用 Chrome 開發人員工具中的 Chrome 的持續繪製模式,即可瞭解哪些 CSS 資源對您產生費用。
  2. 將 CSS 審查融入現有的程式碼審查程序,以找出效能問題 請在 CSS 中找出在一些使用溫度較高的項目 (例如漸層和陰影) 的地方。問問自己,我真的有必要嗎?
  3. 如有疑問,請一律優先提升效能。使用者可能不記得欄內的邊框間距寬度,但會記得造訪網站的感受。

結論

這項實驗最有趣的部分之一,就是隨著各 Chrome 版本 (速度速度快到) 的改變,瀏覽器軟體的更新時間也不會改變。今日的網路速度很慢,可能明天很速。您可以直接移除本文,避免將 box-shadow: 1px 2px 3px 4px 加入已具有 border-radius:5 的元素。不過,相較之下,CSS 資源會直接影響網頁繪製時間。

參考資料