當我們透過某些行為(點擊、移動或滾動)觸發頁面進行大面積繪製的時候,瀏覽器往往是沒有準備的,只能被動使用CPU去計算與重繪,由於沒有事先準備,應付渲染夠嗆,於是掉幀卡頓。而CSS屬性will-change為web開發者提供了一種告知瀏覽器該元素會有哪些變化的方法,這樣瀏覽器可以在元素屬性真正發生變化之前提前做好對應的優化準備工作。這種優化可以將一部分複雜的計算工作提前準備好,使頁面的反應更為快速靈敏。本文將介紹CSS屬性will-change
GPU是圖形處理器,專門處理和繪製圖形相關的硬體。 GPU是專為執行複雜的數學和幾何計算而設計的,使得CPU從圖形處理的任務中解放出來,可以執行其他更多的系統任務
所謂硬體加速,就是在計算機中把計算非常豐富的工作分配給專門的硬體來處理,減輕CPU的工作量
CSS的動畫、變形、漸變並不會自動觸發GPU加速,而是使用瀏覽器稍慢的軟體渲染引擎。在transition
、transform
和animation
的世界裡,應該卸載進程到GPU以加速速度。只有3D變形會有自己的layer,而2D變形則不會
【Hack】
使用translateZ()
或translate3d()
方法為元素添加沒有變化的3D變形,騙取瀏覽器觸發硬體加速。但是,代價是這種情況透過向它自己的層疊加元素,佔用了RAM和GPU的儲存空間,且無法確定空間釋放時間
will-change
功能: 提前通知瀏覽器元素將要做什麼動畫,讓瀏覽器提前準備合適的優化設定
值: auto | < ;animateable-feature>
初始值: auto
應用於: 所有元素
繼承性: 無
應用於: 所有元素
繼承性: 無
相容性: IE13+、相容性: IE13+、相容性: IE13+、相容性: chrome49+、safari9.1+、IOS9.3+、Android52+ auto表示沒有特別指定哪些屬性會變化,瀏覽器需要自己去猜,然後使用瀏覽器經常使用的一些常規方法優化
<animateable-feature>
可以是以下值:
scroll-position
表示開發者希望在不久後改變滾動條的位置或者使之產生動畫
contents
表示開發者希望在不久後改變元素內容中的某些東西,或使它們產生動畫
使用
【使用hover】
不要像下面這樣直接寫在預設狀態中,因為will-change會一直掛著:
.will-change { will-change: transform; transition: transform 0.3s; } .will-change:hover { transform: scale(1.5); }
可以讓父元素hover的時候,聲明will-change,這樣,移出的時候就會自動remove,觸發的範圍基本上是有效元素範圍<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">.will-change-parent:hover .will-change {
will-change: transform;
}
.will-change {
transition: transform 0.3s;
}
.will-change:hover {
transform: scale(1.5);
}</pre><div class="contentsignin">登入後複製</div></div>
【使用javascript腳本】
.sidebar { will-change: transform; }
以上示例在樣式表中直接添加了will-change屬性,會導致瀏覽器將對應的優化工作一直保存在記憶體中,其實是不必要的。以下展示如何使用腳本正確地應用
will-change屬性
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'; }
【直接使用】
.slide { will-change: transform; }
注意事項
*&* 1、不要將will-change應用到太多元素:瀏覽器已經盡力嘗試去優化一切可以優化的東西了。有一些更強的優化,如果與will-change結合在一起的話,有可能會消耗很多機器資源,如果過度使用的話,可能導致頁面響應緩慢或者消耗非常多的資源*&**&* 2、有節制地使用:通常,當元素恢復到初始狀態時,瀏覽器會丟棄掉先前所做的最佳化工作。但如果直接在樣式表中明確聲明了will-change屬性,則表示目標元素可能會經常變化,瀏覽器會將最佳化工作保存得比之前更久。所以最佳實踐是當元素變化之前和之後透過腳本來切換will-change的值*&*3、不要過早應用will-change優化:如果頁面在效能方面沒什麼問題,則不要添加will-change屬性來榨取一丁點的速度。 will-change的設計初衷是作為最後的最佳化手段,用來嘗試解決現有的效能問題。它不應該被用來預防性能問題。過度使用will-change會導致大量的記憶體佔用,並會導致更複雜的渲染過程,因為瀏覽器會試圖準備可能存在的變化過程。這會導致更嚴重的效能問題
4、給它足夠的工作時間:這個屬性是用來讓頁面開發者告知瀏覽器哪些屬性可能會變化的。然後瀏覽器可以選擇在變化發生前事先做一些優化工作。所以給瀏覽器一點時間去真正做這些優化工作是非常重要的。使用時需要嘗試去找到一些方法提前一定時間獲知元素可能發生的變化,然後為它加上will-change屬性
更多CSS頁面渲染優化屬性will-change 相關文章請關注PHP中文網!