當觸發scroll、resize這類的滾動事件時,被觸發的頻率很是高,間隔也特別近。若是事件中涉及到大量的位置計算、DOM操做、元素重繪等工做,而且這些工做沒法在下一個scroll事件出發前完成,就會形成瀏覽器掉幀(掉幀就是例如圖像一閃一閃的,運動不流暢的狀況)。加之用戶鼠標滾動每每是連續的,就會持續觸發scroll事件致使掉幀擴大、瀏覽器CPU使用率增長,用戶體驗收到影響。html
而CSS屬性will-change爲web開發者提供了一種告知瀏覽器該元素會有哪些變化的方法,這樣瀏覽器就能夠在元素屬性真正發生變化以前提早作好對應的優化準備工做。這種優化能夠將一部分複雜的計算工做提早準備好,使頁面的反應更爲快速靈敏。web
CPU即中央處理器,它的功能主要是解釋計算機指令以及處理計算機軟件中的數據,也被稱爲主板。瀏覽器
GPU是圖形處理器,專門處理和繪製圖形相關的硬件。GPU是專爲執行復雜的數學和幾何計算而設計的,使得CPU從圖形處理的任務中解放出來,能夠執行其餘更多的系統任務。bash
硬件加速意味着Graphics Processing Unit(GPU)會經過代替Central Processing Unit (CPU)作一些負荷比較大的事情,來協助瀏覽器快速渲染頁面,當CSS操做使用硬件加速的時候,一般會使頁面渲染速度加快。服務器
瀏覽器渲染頁面的過程:ide
1.解析HTML(HTML Parser)性能
2.構建DOM樹(DOM Tree)優化
3.渲染樹構建(Render Tree)動畫
4.繪製渲染樹(Painting)ui
簡單的解釋就是:瀏覽器經過請求獲得服務器返回的html,由於html是樹狀結構,經過瀏覽器解析生成DOM Tree。在CSS解析完畢後,將獲得的模擬樹CSSOM Tree和DOM Tree結合構建Render Tree,最終用來進行繪圖(Painting)
CSS的動畫、變形、漸變並不會自動觸發GPU加速,而是使用瀏覽器稍慢的軟件渲染引擎。在transition、transform和animation的世界裏,應該卸載進程到GPU以加速速度。只有3D變形會有本身的layer,而2D變形則不會。
will-change的功能是:提早通知瀏覽器元素將要作什麼動畫,讓瀏覽器提早準備合適的優化設置
官方文檔說:這是一個仍處於試驗階段的功能,因此在將來版本的瀏覽器中該語法的功能和行爲kennel隨之變化。
CSS3 will-change屬於web標準屬性,兼容性這塊Chrome/FireFox/Opera都是支持的。
will-change: auto
will-change: scroll-position
will-change: contents
will-change: transform // Example of <custom-ident>
will-change: opacity // Example of <custom-ident>
will-change: left, top // Example of two <animateable-feature>
will-change: unset
will-change: initial
will-change: inherit
複製代碼
表示沒有特別指定哪些屬性會變化,須要瀏覽器本身去猜,而後使用瀏覽器常用的一些常規方法進行優化。
能夠是如下值:
表示開發者但願在不久後改變滾動條的位置或者使之產生動畫
表示開發者但願在不久後改變元素內容中的某些東西,或者使它們產生動畫
表示開發者但願在不久後改變指定的屬性名或者使之產生動畫。若是屬性名是簡寫,則表明全部與之對應的簡寫或者全寫的屬性
不要直接寫在默認狀態中,由於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);
}
複製代碼
var el = document.getElementById('element');
// 當鼠標移動到該元素上時給該元素設置 will-change 屬性
el.addEventListener('mouseenter', hintBrowser);
// 當 CSS 動畫結束後清除 will-change 屬性
el.addEventListener('animationEnd', removeHint);
function hintBrowser() {
// 填寫上那些你知道的,會在 CSS 動畫中發生改變的 CSS 屬性名們
this.style.willChange = 'transform, opacity';
}
function removeHint() {
this.style.willChange = 'auto';
}
複製代碼
若是某個應用在按下鍵盤的時候會翻頁,好比相冊或者幻燈片一類的,它的頁面很大很複雜,此時在樣式表中寫上 will-change 是合適的。這會使瀏覽器提早準備好過渡動畫,當鍵盤按下的時候就能當即看到靈活輕快的動畫。
.slide {
will-change: transform;
}
複製代碼
瀏覽器已經盡力嘗試去優化一切能夠優化的東西了。有一些更強力的優化,若是與 will-change 結合在一塊兒的話,有可能會消耗不少機器資源,若是過分使用的話,可能致使頁面響應緩慢或者消耗很是多的資源。
一般,當元素恢復到初始狀態時,瀏覽器會丟棄掉以前作的優化工做。可是若是直接在樣式表中顯式聲明瞭 will-change 屬性,則表示目標元素可能會常常變化,瀏覽器會將優化工做保存得比以前更久。因此最佳實踐是當元素變化以前和以後經過腳原本切換 will-change 的值。
若是你的頁面在性能方面沒什麼問題,則不要添加 will-change 屬性來榨取一丁點的速度。 will-change 的設計初衷是做爲最後的優化手段,用來嘗試解決現有的性能問題。它不該該被用來預防性能問題。過分使用 will-change 會致使大量的內存佔用,並會致使更復雜的渲染過程,由於瀏覽器會試圖準備可能存在的變化過程。這會致使更嚴重的性能問題。
這個屬性是用來讓頁面開發者告知瀏覽器哪些屬性可能會變化的。而後瀏覽器能夠選擇在變化發生前提早去作一些優化工做。因此給瀏覽器一點時間去真正作這些優化工做是很是重要的。使用時須要嘗試去找到一些方法提早必定時間獲知元素可能發生的變化,而後爲它加上 will-change 屬性。