1. 程式人生 > 其它 >css3屬性: will-change

css3屬性: will-change

1. CPU和GPU

CPU即中央處理器,它的功能主要是解釋計算機指令以及處理計算機軟體中的資料,也被稱為主機板。

GPU即圖形處理器,是與處理和繪製圖形相關的硬體。GPU是專為執行復雜的數學和幾何計算而設計的,有了它,CPU就從圖形處理的任務中解放出來,可以執行其他更多的系統任務

硬體加速(或者說GPU加速)是指在計算機中透過把計算量非常大的工作分配給專門的硬體來處理來減輕CPU的工作量的技術。在csstransition, transform和animation的世界裡,他暗示我們應該解除安裝程序到GPU,因此加快速度。這種情況通過向它自己的層疊加元素,當載入動畫的時候可以加速渲染。

硬體加速依賴於瀏覽器渲染頁面使用的layering model,當特定的操作(css3D變形)作用於頁面上的一個元素,元素移動到它自己的layer,在這個layer中元素合一不受頁面其他元素的干擾獨立渲染,然後複合到頁面中去。在這種隔離內容渲染的工作方式下,如果頁面的變化僅僅是該元素的變形,其餘部分不必被重新渲染,這會帶來顯著的速度優勢。值得注意的是只有3D變形會有自己的layer,2D變形不會。

CSS的動畫、變形、漸變並不會自動的觸發GPU加速,而是使用瀏覽器稍慢的軟體渲染引擎。然而一些瀏覽器提供了hardware acceleration by means of certain properties來獲取更高的渲染效能。 舉個例子,opacity屬性是幾個能夠加速的屬性之一,因為GPU可以方便的處理。基本上任何層的透明度漸變瀏覽器都會交給GPU處理來加速。除了opacity能夠使用GPU處理的就是CSS 3D變形了

2. translateZ() (or translate3d()) Hack

我們都通過translateZ()或者translate3d() hack來騙取瀏覽器觸發硬體加速,具體做法就是為元素新增沒有變化的3D變形,比如元素在2維空間可以通過新增以下CSS來硬體加速

transform: translate3d(0, 0, 0);

然而強制使用hack方式建立layer並不是長久之計,建立layer的技術可以使頁面加速,但是也有代價,它們佔用RAM和GPU儲存空間(考慮到移動裝置的儲存容量有限),所以必須小心使用,確保這麼做真的對頁面渲染有所幫助。為了避免建立layer的hacks,一個允許我們提前通知瀏覽器我們將對元素做何種變化的CSS屬性被引入,這樣瀏覽器可以優化處理元素渲染的方式,為元素提前準備昂貴的動畫處理操作,這就是wiil-change屬性。

3.wiil-change

will-change屬性可以提前通知瀏覽器我們要對元素做什麼動畫,這樣瀏覽器可以提前準備合適的優化設定。這樣可以避免對頁面響應速度有重要影響的昂貴成本。元素可以更快的被改變,渲染的也更快,這樣頁面可以快速更新,表現的更加流暢。

當對於素使用 CSS 3D變形時,元素及其內容可以在合成到頁面之前被建立到我們之前說的layer。然而把元素放到layer中是個昂貴的操作,這將會導致變形動畫延遲一個課件的瞬間,也就是flicker
為了避免這種延時,我們可以在發生之前通知瀏覽器,這樣瀏覽器會有一定的時間去準備這些變化,當發生的時候layer已經準備好了,這樣動畫酒會很流暢,不會閃屏。

will-change: transform;

可以寫多個屬性變化,逗號隔開

will-change: transform, opacity;

注意事項:

不要將 will-change 應用到太多元素上:瀏覽器已經盡力嘗試去優化一切可以優化的東西了。有一些更強力的優化,如果與 will-change 結合在一起的話,有可能會消耗很多機器資源,如果過度使用的話,可能導致頁面響應緩慢或者消耗非常多的資源。濫用會使頁面崩潰。。。

*,
*::before,
*::after {
    will-change: all;
}
雖然看起來很屌,但其實對頁面渲染傷害很大,這樣的規則設了和沒設沒什麼區別,瀏覽器本來就嘗試最優的渲染所有元素,就等於你讓老師重點照顧班裡每個同學一樣,就是廢話!
其實這甚至是有害的,因為一些操作會佔用太多的資源,甚至會導致頁面奔潰,就等於強制要求老師為每個學生補課,累死了。。。

有節制地使用:通常,當元素恢復到初始狀態時,瀏覽器會丟棄掉之前做的優化工作。但是如果直接在樣式表中顯式聲明瞭 will-change 屬性,則表示目標元素可能會經常變化,瀏覽器會將優化工作儲存得比之前更久。所以最佳實踐是當元素變化之前和之後通過指令碼來切換 will-change 的值。

https://www.98891.com/article-30-1.html

不要過早應用 will-change 優化:如果你的頁面在效能方面沒什麼問題,則不要新增 will-change 屬性來榨取一丁點的速度。 will-change 的設計初衷是作為最後的優化手段,用來嘗試解決現有的效能問題。它不應該被用來預防效能問題。過度使用 will-change 會導致大量的記憶體佔用,並會導致更復雜的渲染過程,因為瀏覽器會試圖準備可能存在的變化過程。這會導致更嚴重的效能問題。

給它足夠的工作時間:這個屬性是用來讓頁面開發者告知瀏覽器哪些屬性可能會變化的。然後瀏覽器可以選擇在變化發生前提前去做一些優化工作。所以給瀏覽器一點時間去真正做這些優化工作是非常重要的。使用時需要嘗試去找到一些方法提前一定時間獲知元素可能發生的變化,然後為它加上 will-change 屬性。

在變化前立即為元素新增will-change幾乎沒有作用,可能還不如不設定,因為會導致新的layer建立,如下:

.element:hover {
    will-change: transform;
    transition: transform 2s;
    transform: rotate(30deg) scale(1.5);
}

需要給瀏覽器足夠的時間,如下:

.element {
    /* style rules */
    transition: transform 1s ease-out;
}
.element:hover {
    will-change: transform;
}
.element:active {
    transform: rotateY(180deg);
}
will-change顧名思義,通知瀏覽器即將發生的變化,而不是正在發生的變化。使用will-change,我們要求瀏覽器重點照顧我們宣告的元素,為了這個瀏覽器需要一定的時間來組織優化操作,這樣當變化發生的時候,優化才能沒有延遲的作用到元素

語法:

/* 關鍵字值 */
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;
 
## auto ## 
表示沒有特別指定哪些屬性會變化,瀏覽器需要自己去猜,然後使用瀏覽器經常使用的一些常規方法優化。
## <animateable-feature> ##
 1) scroll-position 告訴瀏覽器,要不久後動畫啦(改變滾動條的位置或者使之產生動畫)
 2) contents:告訴瀏覽器 不久後改變元素內容中的某些東西,或者使它們產生動畫。
## <custom-ident> ## 
不久後改變指定的屬性名或者使之產生動畫。如果屬性名是簡寫,則代表所有與之對應的簡寫或者全寫的屬性。

瀏覽器相容性:

Desktop

FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support 36 36 (36)[1] 未實現 24 未實現

Mobile

FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support 37 36.0 (36) [1] 未實現 未實現 未實現