1. 程式人生 > >CSS3 will-change提高頁面動畫等渲染效能

CSS3 will-change提高頁面動畫等渲染效能

今天突然看到這個will-change 覺得好新鮮,就百度一看,才知道人家早就出來(我out了),只是現在各個瀏覽器還不怎麼相容,為了滿足我的好奇心,就來了解下唄。

如果你已經試驗和利用過這些CSS3的屬性,你可能碰到類似CPU、GPU和硬體加速等術語。讓我們快速的掌握這些術語:
   ①CPU即中央處理器,它的功能主要是解釋計算機指令以及處理計算機軟體中的資料,也被稱為主機板。
   ②GPU即圖形處理器,是與處理和繪製圖形相關的硬體。GPU是專為執行復雜的數學和幾何計算而設計的,有了它,CPU就從圖形處理的任務中解放出來,可以執行其他更多的系統任務。
   ③硬體加速是指在計算機中透過把計算量非常大的工作分配給專門的硬體來處理來減輕CPU的工作量的技術。在CSS transition, transform和animation的世界裡,他暗示我們應該解除安裝程序到GPU,因此加快速度。這種情況通過向它自己的層疊加元素,當載入動畫的時候可以加速渲染。
怎樣改善動畫的效能和質量?首先,在基於webkit的瀏覽器,我們在執行一些CSS的操作經常會看見閃爍和動畫。在過去,我們通過欺騙瀏覽器一點點解決實現。我們會使瀏覽器執行3D變換,因此減輕了工作量到GPU上。這是因為3D轉換是自動移到那裡的。這導致我們的做一些掛羊頭賣狗肉的事就像這樣:
.accelerate {
  -webkit-transform: translate3d(0, 0, 0);
}
還有一些類似的技巧,但是在大部分情況下,有很多相同的技巧,但對於此類問題的大部分,這種方式就可以解決。然而, 這是一種非正常的實現方式,當我們正確使用的時候,will-change屬性將極大的幫助我們。讓我們一起探討一下吧。

一.will-change

1.是什麼?

CSS3 will-change屬於web標準屬性,相容性這塊Chrome/FireFox/Opera都是支援的。

注意:will-change真正的行為觸發之前會告訴瀏覽器:“我要觸發啦”。這意味著不是通過一個3D變換迫使我們轉換到GPU,而是我們現在可以使用一個專用的屬性來通知瀏覽器留意接下來的變化,從而優化和分配記憶體。提前預約從容不迫。

2.語法

/* 關鍵字值 */
will-change: auto;
will-change: scroll-position;
will-change: contents;
will-change: transform;        /* <custom-ident>示例 */
will-change: opacity;          /* <custom-ident>示例 */
will-change: left, top;        /* 兩個<animateable-feature>示例 */

/* 全域性值 */
will-change: inherit;
will-change: initial;
will-change: unset;

1.<animateable-feature> 可以是以下值:
scroll-position 告訴瀏覽器,要不久後動畫啦(改變滾動條的位置或者使之產生動畫)
contents:告訴瀏覽器 不久後改變元素內容中的某些東西,或者使它們產生動畫。
<custom-ident>:不久後改變指定的屬性名或者使之產生動畫。如果屬性名是簡寫,則代表所有與之對應的簡寫或者全寫的屬性。

3.使用

不要這樣直接寫在預設狀態中,因為will-change會一直掛著

.will-change {
  will-change: transform;
  transition: transform 0.3s;
}
.will-change:hover {
  transform: scale(1.5);
}
可以讓父元素hover的時候,宣告will-change,這樣,移出的時候就會自動remove,觸發的範圍基本上是有效元素範圍。
.will-change-parent:hover .will-change {
  will-change: transform;
}
.will-change {
  transition: transform 0.3s;
}
.will-change:hover {
  transform: scale(1.5);
}
如果使用JS新增will-change, 事件或動畫完畢,一定要及時remove. 比方說點選某個按鈕,其他某個元素進行動畫。點選按鈕(click),要先按下(mousedown)再擡起才出發。因此,可以mousedown時候打聲招呼, 動畫結束自帶回調,於是(示意,不要在意細節):
var el = document.getElementById('element');
// 當滑鼠移動到該元素上時給該元素設定 will-change 屬性
el.addEventListener('mouseenter', hintBrowser);
// animationend 事件在 CSS 動畫完成後觸發。當 CSS 動畫結束後清除 will-change 屬性
el.addEventListener('animationend', removeHint);
function hintBrowser() {
  this.style.willChange = 'transform, opacity';
}
function removeHint() {
  this.style.willChange = 'auto';
}