1. 程式人生 > 實用技巧 >兩張圖解釋CSS動畫的效能

兩張圖解釋CSS動畫的效能

在手機上使用css動畫時很多時候會感到卡頓,然後網上很多教程說開啟GPU加速transform: translate3d(0,0,0);可解決,但是為什麼開啟GPU加速就能讓動畫順滑呢?

我們從瀏覽器內部去理解下

js是單執行緒的,但是瀏覽器可以開啟多個執行緒,渲染一個網頁需要兩個重要的執行緒來共同完成:

  • Main Thread 主執行緒
  • Compositor Thread 繪製執行緒(我自己翻譯的)

主執行緒的工作:

  1. 執行js
  2. 計算html元素的css樣式
  3. 佈局頁面
  4. 將元素繪製到一個或多個位圖中
  5. 把這些點陣圖交給 Compositor Thread 來處理

繪製執行緒的工作:

  1. 通過 GPU 將點陣圖繪製到螢幕上
  2. 通知主執行緒去更新頁面中可見或即將可見的部分的點陣圖
  3. 計算出頁面中那些部分是可見的
  4. 計算出在滾動頁面時候,頁面中哪些部分是即將可見的
  5. 滾動頁面時將相應位置的元素移動到可視區

我們知道如果長時間的執行 JS 會阻塞主執行緒,頁面就會出現各種的卡頓。

而繪製執行緒會盡量的去響應使用者的互動,頁面發生變化時,繪製執行緒會以每秒60幀(因為每秒60幀是最適合人眼的互動,小於60就會明顯感覺到卡頓了)的間隔不斷重繪頁面。

GPU 在如下方面很快:

  • 繪製點陣圖到螢幕上
  • 可不斷的繪製相同的點陣圖
  • 將同一點陣圖進行位移、旋轉、縮放 (就是動畫)

但是在將點陣圖載入到GPU記憶體中有點慢

關於兩張圖的正題來了

PS: 橙色方框的操作比較耗時,綠色方框的操作比較快速
div {
    height: 100px;
    transition: height 1s linear;
}

div:hover {
    height: 200px;
}

一個從height: 100px到height: 200px的動畫按照下面的流程圖來執行各種操作

圖中有那麼多的橙色方框,瀏覽器會做大量的計算,動畫就會卡頓。

因為每一幀的變化瀏覽器都在進行佈局、繪製、把新的點陣圖交給 GPU 記憶體(這恰好是我們上面提到的GPU的短板)

雖然只改變元素高度但是很可能要同步改變他的子元素的大小,那瀏覽器就要重新計算佈局,計算完後主執行緒再來重新生成該元素的點陣圖。

廣州品牌設計公司https://www.houdianzi.com PPT模板下載大全https://redbox.wode007.com

使用 transform 屬性的動畫

div {
    transform: scale(0.5);
    transition: transform 1s linear;
}

div:hover {
    transform: scale(1.0);
}

流程圖如下

很明顯,這麼少的橙色方框,動畫肯定會流暢。

因為transform屬性不會改變自己和他周圍元素的佈局,他會對元素的整體產生影響。

因此,瀏覽器只需要一次生成這個元素的點陣圖,然後動畫開始時候交給 GPU 來處理他最擅長的位移、旋轉、縮放等操作。這就解放了瀏覽器不再去做各種的佈局、繪製等操作。