兩張圖解釋CSS動畫的效能
阿新 • • 發佈:2020-12-09
在手機上使用css動畫時很多時候會感到卡頓,然後網上很多教程說開啟GPU加速transform: translate3d(0,0,0);可解決,但是為什麼開啟GPU加速就能讓動畫順滑呢?
我們從瀏覽器內部去理解下
js是單執行緒的,但是瀏覽器可以開啟多個執行緒,渲染一個網頁需要兩個重要的執行緒來共同完成:
- Main Thread 主執行緒
- Compositor Thread 繪製執行緒(我自己翻譯的)
主執行緒的工作:
- 執行js
- 計算html元素的css樣式
- 佈局頁面
- 將元素繪製到一個或多個位圖中
- 把這些點陣圖交給 Compositor Thread 來處理
繪製執行緒的工作:
- 通過 GPU 將點陣圖繪製到螢幕上
- 通知主執行緒去更新頁面中可見或即將可見的部分的點陣圖
- 計算出頁面中那些部分是可見的
- 計算出在滾動頁面時候,頁面中哪些部分是即將可見的
- 滾動頁面時將相應位置的元素移動到可視區
我們知道如果長時間的執行 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 來處理他最擅長的位移、旋轉、縮放等操作。這就解放了瀏覽器不再去做各種的佈局、繪製等操作。