溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

css中will-change屬性的示例分析

發布時間:2021-06-28 11:35:24 來源:億速云 閱讀:233 作者:小新 欄目:web開發

這篇文章主要介紹了css中will-change屬性的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

will-change

CSS 屬性 will-change 為web開發者提供了一種告知瀏覽器該元素會有哪些變化的方法,這樣瀏覽器可以在元素屬性真正發生變化之前提前做好對應的優化準備工作。 這種優化可以將一部分復雜的計算工作提前準備好,使頁面的反應更為快速靈敏。

重要提示:will-change 旨在用作嘗試處理現有的性能問題的最后手段。 它不應該用于預測性能問題。

替換 translateZ() Hack

例如,當使用 CSS 3D 變換(transform)在屏幕上移動元素時,元素及其內容可能會被提升到一個“層”(layer),在那里它們可以獨立于頁面的其余部分進行渲染,并在以后進行合成。這樣隔離了內容的呈現,如果元素的變換(transform)是在幀之間發生變化的唯一內容,則不必重新渲染頁面的其余部分,并且通常提供顯著的速度優勢。

然而,在新層(layer)中設置元素是一項相對昂貴的操作,它可以將變換動畫的開始延遲明顯的幾分之一秒。

為了避免在使用 CSS Transforms 和其他 CSS 操作時出現這種延遲,我們長期以來一直使用 translateZ(或有時是 translate3d)將元素提升到它們自己的層,從而實現硬件加速操作,以運行更流暢、更快,沒有毛刺。 然而,這種技術——也被稱為“translateZ()(或 translate3d()) Hack”——是有代價的。 保羅劉易斯寫了一篇關于這個的非常有用的帖子,如果你使用這種技術,你一定要檢查一下。 will-change 是為了讓我們能夠優化我們的動畫,而不必求助于這個 hack——或者任何其他 hack。

(學習視頻分享:css視頻教程)

逗號分隔

您可以通過指定您希望更改的屬性名稱(以逗號分隔)來向瀏覽器聲明您打算更改元素的滾動位置、其內容或其一個或多個 CSS 屬性值。 大多數屬性在指定時將不起作用,因為用戶代理不會對大多數屬性的更改執行任何特殊優化。 不過,指定它們仍然是安全的,雖然根本沒有效果。

如果您期望或計劃更改元素的多個值/方面,您可以提供逗號分隔值的列表。 逗號分隔值列表可以包括預定義的關鍵字和/或屬性名稱。 (請參閱下面的示例部分。)

額外創建堆疊上下文和包含塊

如果您聲明的屬性的任何非初始值會在元素上創建堆疊上下文,則在 will-change 中指定該屬性一定在元素上創建堆疊上下文。 例如,將 opacity 設置為 1 以外的任何值都會在元素上創建堆疊上下文。 因此,設置 will-change: opacity 也會創建一個堆疊上下文,即使 opacity 當前仍然等于 1。

類似地,如果屬性的任何非初始值會導致元素為固定位置元素生成包含塊,則在 will-change 中指定該屬性必須導致元素為固定位置元素生成包含塊。

will-change 屬性對它指定的元素沒有直接影響,除了前面提到的創建堆疊上下文和包含塊之外——它只是對用戶代理的渲染提示,允許它在某些類型的更改實際開始發生之前設置潛在昂貴的優化。

謹慎使用

話雖如此,重要的是您知道應謹慎使用此屬性。 不同的瀏覽器可以以不同的方式使用來自 will-change 的信息,甚至單個瀏覽器也可能在不同的時間以不同的方式使用它。過度使用它可能會導致完全忽略聲明。例如,當元素有 will-change 時,將元素提升到它們自己的“GPU 層”的瀏覽器。但有太多元素聲明時,瀏覽器將忽略聲明,以避免耗盡 GPU 內存。

此外,除非已知或預計元素會在不久的將來(例如,在幾分之一秒內)發生變化,否則不應使用 will-change。 一旦不再需要它,就應該取消設置:

在實際更改的元素上將 will-change 設置為您將實際更改的屬性。 并在他們停止時將其刪除。 - Tab Atkins Jr.(規范編輯者)

瀏覽器對即將發生的更改進行的優化通常代價高昂,而且正如我們前面提到的,會占用非常多的機器資源。通常瀏覽器優化行為是刪除這些優化并盡快恢復到正常行為。 然而,will-change 會覆蓋這種行為,保持優化的時間比瀏覽器其他場景下更長。

因此,您應該始終記住在元素完成更改后刪除 will-change,以便瀏覽器可以恢復優化聲明的任何資源。

使用 JavaScript 設置  will-change

通過 JavaScript 設置 will-change 允許更細粒度的控制,和更多瀏覽器準備更改的時間,并且還允許您在動畫事件結束后立即取消設置。 使用 JavaScript,您可以向瀏覽器聲明您的更改,然后在更改完成后通過監聽這些更改何時完成來刪除 will-change。

例如,您可以監聽元素(或其祖先)何時懸停,然后在 mouseenter 上設置 will-change。 如果你的元素正在被動畫化,你可以使用 DOM 事件 animationEnd 監聽動畫何時結束,然后在 animationEnd 被觸發后移除 will-change。

// Rough generic example
// Get the element that is going to be animated on click, for example
var el = document.getElementById('element');

// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
	// The optimizable properties that are going to change
	// in the animation's keyframes block
	this.style.willChange = 'transform, opacity';
}

function removeHint() {
	this.style.willChange = 'auto';
}

更好的在 css 中設置 will-change

如果您確實想在樣式表中設置 will-change 以針對可能在懸停時更改的元素進行優化,那么為了告訴瀏覽器針對您希望在懸停時發生的更改進行優化,您可以執行以下操作 :

.el:hover {
    will-change: transform;
    transform: rotate()...;
}

這并不是特別錯誤,但也不是特別有用。您需要在更改實際發生之前的某個時間向瀏覽器聲明您的意圖,而不是在更改發生時,以便給它一些時間來準備更改并進行所需的優化。所以,在這樣的場景中,你可以這樣做:

.el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}

或者,您可以在元素的容器懸停時設置 will-change,因為懸停事件到達元素本身需要一些時間,然后瀏覽器可以使用該時間為元素本身的更改做準備:

.container:hover .el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}

總結一下,記得謹慎使用 will-change,不要過度使用,只有在知道元素即將改變時才設置它,并且記得在改變完成后取消設置。

官方語法

  • 聲明:

will-change: auto | <animateable-feature>#

其中

<animateable-feature> = scroll-position | contents | <custom-ident>

標簽 (#) 表示您可以指定多個值,多個值以逗號分隔。

  • 初始值:auto

  • 適用于:所有元素

  • 動畫:否

值(Values)

auto

這是默認值。 它沒有表達特別的意圖。 瀏覽器不會收到任何更改的通知,因此不會進行任何優化以適應未來的任何更改。

scroll-position

表示作者希望在不久的將來動畫或更改元素的滾動位置。 瀏覽器會提前針對此更改進行適當的優化。

例如,瀏覽器通常只在可滾動元素上呈現“滾動窗口”中的內容,以及已經經過該窗口的內容,從而平衡好跳過渲染所節省的時間和內存,以使滾動看起來更好看。瀏覽器可能會將此值作為信號來擴展呈現的滾動窗口周圍的內容范圍,以便可以平滑地完成更長/更快的滾動。

contents

表示作者希望在不久的將來動畫或更改元素內容的某些內容。 瀏覽器會提前針對此更改進行適當的優化。

例如,瀏覽器經常會隨著時間的推移“緩存”元素的渲染,因為大多數東西不會經常改變,或者只是改變它們的位置。 但是,如果元素確實定期更改其內容,那么生成和維護此緩存就是浪費時間。瀏覽器可能會將這個值作為一個信號,在元素上不那么積極地緩存,或者根本避免緩存而只是不斷地從頭開始重新渲染元素。

<custom-ident> (<user-ident>)

<custom-ident> 值(有關詳細信息,請參閱 <custom-ident> 條目)。 表示作者希望在不久的將來對元素上具有給定名稱的屬性進行動畫處理或更改。

例如,瀏覽器通常將設置有非初始值 transform 屬性的元素和其他元素區分開,可能將它們渲染到自己的“GPU 層”,或者使用其他機制來更容易的快速的進行變換。瀏覽器可能會將 transform 的值作為一個信號,表明它應該在元素開始轉換之前立即將元素提升到它自己的層,以避免重新渲染舊層和新層所涉及的任何延遲。

除了通常從 <custom-ident> 中排除的關鍵字之外,<custom-ident> 值不能是以下關鍵字之一:will-change、none、all、auto、scroll-positioncontents。

請注意,大多數屬性在指定時將不起作用,因為用戶代理不會對大多數屬性的更改執行任何特殊優化。不過,指定它們仍然是安全的,雖然它根本沒有效果。

注:感覺雖然命名為『自定義標志』, 其實主要碰到的還是 css 預定義好的標志,譬如 transform、opacity

例子

下面告訴瀏覽器期望元素的變換屬性發生變化,以便提前進行適當的優化。

.el {
    will-change: transform;
}

上面的 will-change 聲明應該通過 JavaScript 添加,然后在更改結束后刪除或取消設置 (will-change: auto)。

以下所有的都是可能且有效的 will-change 值:

will-change: contents;
will-change: scroll-position;
will-change: opacity;/* multiple comma-separated values */will-change: contents, transform;
will-change: scroll-position, opacity;

使用小結

想使用好 will-change 并不是太容易,以下使用忠告摘錄于官方文檔,可見真是太難了。

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

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

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

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

感謝你能夠認真閱讀完這篇文章,希望小編分享的“css中will-change屬性的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

css
AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女