從瀏覽器渲染層面解析 css3 動效優化原理

引言—

在 h5 開發中,我們經常會需要實現一些動效來讓頁面視覺效果更好,談及動效便不可避免地會想到動效性能優化這個話題:

那麼,CSS3 與動效優化有什麼關係呢,本文將從瀏覽器渲染層面講述 CSS3 的動效優化原理

瀏覽器頁面展示過程—

首頁,我們需要了解一下瀏覽器的頁面展示過程:

瀏覽器渲染原理—

在討論 Composite 之前,我們還需要了解一下瀏覽器渲染原理

從該圖中,我們可以發現:

Graphics Layer

我們日常生活中所看到屏幕可視效果可以理解爲:由多個位圖通過 GPU 合成渲染到屏幕上,而位圖的最小單位是像素。如下圖:

那麼位圖是怎麼獲得的呢,Graphics Layer 便起到了關鍵作用, 每個 Graphics Layer 都有一個 Graphics Context, 位圖是存儲在共享內存中,Graphics Context 會負責將位圖作爲紋理上傳到GPU中,再由 GPU 進行合成渲染。如下圖:

CSS 在瀏覽器渲染層面承擔了怎樣的角色

大多數人對於 CSS3 的第一印象,就是可以通過 3D(如 transform) 屬性來開啓硬件加速,許多同學在重構某一個項目時,考慮到動畫性能問題,都會傾向:

  1. 將 2Dtransform 改爲 3Dtransform 2. 將 left (top、bottom、right) 的移動改爲 3Dtransform
    但開啓硬件加速的底層原理其實就在於將 Paint Layer 提升到了 Composite Layer以下的幾種方式都用相同的作用:

我們來寫兩段 demo 代碼,帶大傢俱體分析一下實際情況

demo1. 3D 屬性開啓硬件加速 (3d-transform)

.composited{
  width: 200px;
  height: 200px;
  background: red;
  transform: translateZ(0)
}
</style>

<div class="composited">
  composited - 3dtransform
</div>

可以看到是因爲使用的 CSS 3D transform,創建了一個複合層

demo2. 對 opacity、transform、filter 應用 animation(actived) or transition(actived)

<style>
@keyframes move{
  0%{
    top: 0;
  }
  50%{
    top: 600px;
  }
  100%{
    top: 0;
  }
}
@keyframes opacity{
  0%{
    opacity: 0;
  }
  50%{
    opacity: 1;
  }
  100%{
    opacity: 0;
  }
}

#composited{
  width: 200px;
  height: 200px;
  background: red;
  position: absolute;
  left: 0;
  top: 0;
  
}
.both{
  animation: move 2s infinite, opacity 2s infinite;
}
.move{
  animation: move 2s infinite;
}
</style>

<div  id="composited" class="both">
  composited - animation
</div>
<script>
setTimeout(function(){
  const dom = document.getElementById('composited')
  dom.className = 'move'
},5000)
</script>

這裏我們定義了兩個keyframes(move、opacity),還有兩個class(both、move),起初 #compositedclassName = 'both',5 秒延時器後,className = 'move',我們來看看瀏覽器的實際變化。

起初:#composited 創建了一個複合層,並且運動時 fps 沒有波動,性能很穩定

5 秒後:複合層消失,運動時 fps 會發生抖動,性能開始變得不再穩定

如何查看複合層及 fps

在瀏覽器的 Dev Tools 中選擇 More tools,並勾選 Rendering 中的 FPS meter

動畫性能最優化

之前,我們提到了頁面呈現出來所經歷的渲染流水線,其實從性能方面考慮,最理想的渲染流水線是沒有佈局和繪製環節的,爲了實現上述效果,就需要只使用那些僅觸發 Composite 的屬性。
目前,只有兩個屬性是滿足這個條件的:transformsopacity(僅部分瀏覽器支持)。
相關信息可查看:css Triggers[1]

總結

提升爲合成層簡單說來有以下幾點好處:

缺點:

大多數人都很喜歡使用 3D 屬性 translateZ(0) 來進行所謂的硬件加速,以提升性能。但我們還需要切實的去分析頁面的實際性能表現,不斷的改進測試,這樣纔是正確的性能優化途徑。

參考資料

[1]

css Triggers: https://csstriggers.com/?spm=taofed.bloginfo.blog.36.20e75ac8xZGHBo

[2]

無線性能優化:Composite - 淘系前端團隊: https://fed.taobao.org/blog/taofed/do71ct/performance-composite/?spm=taofed.blogs.header.7.63e65ac801qdAI

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/sVGEQjcfTsljMup2OBoAzQ