歡迎移步個人博客閱讀:《實用的 CSS — 動畫性能對比》css
在現代瀏覽器中,渲染頁面所要負責的線程主要有兩個:主線程和排版線程。html
運行 JScss3
計算 HTML 元素的 CSS 樣式web
佈局頁面瀏覽器
把頁面元素繪製成一個或多個位圖佈局
把這些位圖移交給排版線程性能
在瀏覽器開始渲染頁面,或者長時間執行某個 JS 時,主線程會一直在忙碌狀態,此時對於用戶的任何輸入或是操做都不會有所響應。動畫
經過 GPU 渲染位圖,並顯示在屏幕上spa
向主線程請求更新位圖的可見部分或即將可見的部分線程
判斷出當前頁面處於可見的部分
判斷出即將經過頁面滾動而可見的部分
隨着用戶滾動頁面來移動這些部分
排版線程對於用戶的操做保持快速的響應,廣泛的效率時每秒 60 幀的速度去刷新顯示。
下面咱們在網頁中實現一個元素的高度變化的動畫,鼠標懸浮在元素上動畫啓動,直至完成:
<style> #foo { height: 100px; width: 100px; background: red; transition: height 1s linear; } #foo:hover { height: 200px; } </style> <body> <div id="foo"></div> </body>
經過對上述代碼的觀察,讓咱們來了解一下瀏覽器的兩個線程是如何協同工做的:
圖中橘黃色部分表明操做相對較慢,消耗較大;藍色部分表明操做相對較快,消耗較小
從上圖咱們能夠看到,瀏覽器的兩個線程在來回地切換工做,並且橘黃色出現次數較多,這意味着瀏覽器須要處理至關多的工做。
對於瀏覽器而言,因爲元素的高度一直在變化,所以這個動畫的每一幀中,都須要從新佈局 ——> 繪製頁面 ——> 將新的位圖加載到 GPU 中 ——> 顯示。而其中加載到 GPU
是一個相對緩慢的操做。
同時咱們也在經過瀏覽器去查看元素動畫的過程,實際上是由略微卡頓的現象的。
通過上面的實驗,咱們對 transition
屬性有了比較好的瞭解;同時咱們對上述動畫性能也有一個瞭解。接着我須要在網頁中實現一個元素的大小變化動畫,鼠標懸浮在元素上動畫啓動,直至完成:
<style> #bar { height: 100px; width: 100px; background: red; transition: transform 1s linear; } #bar:hover { transform: scale(2); } </style> <body> <div id="bar"></div> </body>
完成上述實驗,再讓咱們來看看兩個線程工做的過程:
由此咱們能夠看到,兩個線程來回切換的狀況並很少,橘黃色部分出現的次數也較少,藍色部分居絕大部分,這意味着這個動畫效果相較於上面的要流暢不少。
在定義中,transform
是不會使瀏覽器產生從新排版的,所以 transform
不會影響本來的佈局,以及周圍的元素。它會將定義的元素做爲一個總體進行縮放、移動或旋轉等。
基於 transform
這類的特性,瀏覽器在渲染頁面時能夠節省不少沒必要要的開支,例如從新佈局和將位圖傳給 GPU 等工做,這樣就使得動畫更有效率。
當頁面須要位移動畫時,咱們有兩種方案:使用 position
或是 transalte
,而這兩種是符合上述狀況的。其中 position
的位移方案與第一個符合,在動畫執行過程當中會使瀏覽器從新渲染;另外一外 transalte
則與第二個符合,在執行動畫時不會發生從新渲染。所以,在須要寫動畫時,咱們須要選擇合適的方案,最好是選擇 scale()
、rotate()
、transalte()
等,由於他們具備更好的性能。
W3C: CSS Transforms
W3C: CSS Transitions
css-animations-and-transitions-performance