溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2021-06-28 11:35:24 來(lái)源:億速云 閱讀:199 作者:小新 欄目:web開(kāi)發(fā)

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

will-change

CSS 屬性 will-change 為web開(kāi)發(fā)者提供了一種告知瀏覽器該元素會(huì)有哪些變化的方法,這樣瀏覽器可以在元素屬性真正發(fā)生變化之前提前做好對(duì)應(yīng)的優(yōu)化準(zhǔn)備工作。 這種優(yōu)化可以將一部分復(fù)雜的計(jì)算工作提前準(zhǔn)備好,使頁(yè)面的反應(yīng)更為快速靈敏。

重要提示:will-change 旨在用作嘗試處理現(xiàn)有的性能問(wèn)題的最后手段。 它不應(yīng)該用于預(yù)測(cè)性能問(wèn)題。

替換 translateZ() Hack

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

然而,在新層(layer)中設(shè)置元素是一項(xiàng)相對(duì)昂貴的操作,它可以將變換動(dòng)畫(huà)的開(kāi)始延遲明顯的幾分之一秒。

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

(學(xué)習(xí)視頻分享:css視頻教程)

逗號(hào)分隔

您可以通過(guò)指定您希望更改的屬性名稱(以逗號(hào)分隔)來(lái)向?yàn)g覽器聲明您打算更改元素的滾動(dòng)位置、其內(nèi)容或其一個(gè)或多個(gè) CSS 屬性值。 大多數(shù)屬性在指定時(shí)將不起作用,因?yàn)橛脩舸聿粫?huì)對(duì)大多數(shù)屬性的更改執(zhí)行任何特殊優(yōu)化。 不過(guò),指定它們?nèi)匀皇前踩?,雖然根本沒(méi)有效果。

如果您期望或計(jì)劃更改元素的多個(gè)值/方面,您可以提供逗號(hào)分隔值的列表。 逗號(hào)分隔值列表可以包括預(yù)定義的關(guān)鍵字和/或?qū)傩悦Q。 (請(qǐng)參閱下面的示例部分。)

額外創(chuàng)建堆疊上下文和包含塊

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

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

will-change 屬性對(duì)它指定的元素沒(méi)有直接影響,除了前面提到的創(chuàng)建堆疊上下文和包含塊之外——它只是對(duì)用戶代理的渲染提示,允許它在某些類型的更改實(shí)際開(kāi)始發(fā)生之前設(shè)置潛在昂貴的優(yōu)化。

謹(jǐn)慎使用

話雖如此,重要的是您知道應(yīng)謹(jǐn)慎使用此屬性。 不同的瀏覽器可以以不同的方式使用來(lái)自 will-change 的信息,甚至單個(gè)瀏覽器也可能在不同的時(shí)間以不同的方式使用它。過(guò)度使用它可能會(huì)導(dǎo)致完全忽略聲明。例如,當(dāng)元素有 will-change 時(shí),將元素提升到它們自己的“GPU 層”的瀏覽器。但有太多元素聲明時(shí),瀏覽器將忽略聲明,以避免耗盡 GPU 內(nèi)存。

此外,除非已知或預(yù)計(jì)元素會(huì)在不久的將來(lái)(例如,在幾分之一秒內(nèi))發(fā)生變化,否則不應(yīng)使用 will-change。 一旦不再需要它,就應(yīng)該取消設(shè)置:

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

瀏覽器對(duì)即將發(fā)生的更改進(jìn)行的優(yōu)化通常代價(jià)高昂,而且正如我們前面提到的,會(huì)占用非常多的機(jī)器資源。通常瀏覽器優(yōu)化行為是刪除這些優(yōu)化并盡快恢復(fù)到正常行為。 然而,will-change 會(huì)覆蓋這種行為,保持優(yōu)化的時(shí)間比瀏覽器其他場(chǎng)景下更長(zhǎng)。

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

使用 JavaScript 設(shè)置  will-change

通過(guò) JavaScript 設(shè)置 will-change 允許更細(xì)粒度的控制,和更多瀏覽器準(zhǔn)備更改的時(shí)間,并且還允許您在動(dòng)畫(huà)事件結(jié)束后立即取消設(shè)置。 使用 JavaScript,您可以向?yàn)g覽器聲明您的更改,然后在更改完成后通過(guò)監(jiān)聽(tīng)這些更改何時(shí)完成來(lái)刪除 will-change。

例如,您可以監(jiān)聽(tīng)元素(或其祖先)何時(shí)懸停,然后在 mouseenter 上設(shè)置 will-change。 如果你的元素正在被動(dòng)畫(huà)化,你可以使用 DOM 事件 animationEnd 監(jiān)聽(tīng)動(dòng)畫(huà)何時(shí)結(jié)束,然后在 animationEnd 被觸發(fā)后移除 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 中設(shè)置 will-change

如果您確實(shí)想在樣式表中設(shè)置 will-change 以針對(duì)可能在懸停時(shí)更改的元素進(jìn)行優(yōu)化,那么為了告訴瀏覽器針對(duì)您希望在懸停時(shí)發(fā)生的更改進(jìn)行優(yōu)化,您可以執(zhí)行以下操作 :

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

這并不是特別錯(cuò)誤,但也不是特別有用。您需要在更改實(shí)際發(fā)生之前的某個(gè)時(shí)間向?yàn)g覽器聲明您的意圖,而不是在更改發(fā)生時(shí),以便給它一些時(shí)間來(lái)準(zhǔn)備更改并進(jìn)行所需的優(yōu)化。所以,在這樣的場(chǎng)景中,你可以這樣做:

.el {
    will-change: transform;
}

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

或者,您可以在元素的容器懸停時(shí)設(shè)置 will-change,因?yàn)閼彝J录竭_(dá)元素本身需要一些時(shí)間,然后瀏覽器可以使用該時(shí)間為元素本身的更改做準(zhǔn)備:

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

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

總結(jié)一下,記得謹(jǐn)慎使用 will-change,不要過(guò)度使用,只有在知道元素即將改變時(shí)才設(shè)置它,并且記得在改變完成后取消設(shè)置。

官方語(yǔ)法

  • 聲明:

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

其中

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

標(biāo)簽 (#) 表示您可以指定多個(gè)值,多個(gè)值以逗號(hào)分隔。

  • 初始值:auto

  • 適用于:所有元素

  • 動(dòng)畫(huà):否

值(Values)

auto

這是默認(rèn)值。 它沒(méi)有表達(dá)特別的意圖。 瀏覽器不會(huì)收到任何更改的通知,因此不會(huì)進(jìn)行任何優(yōu)化以適應(yīng)未來(lái)的任何更改。

scroll-position

表示作者希望在不久的將來(lái)動(dòng)畫(huà)或更改元素的滾動(dòng)位置。 瀏覽器會(huì)提前針對(duì)此更改進(jìn)行適當(dāng)?shù)膬?yōu)化。

例如,瀏覽器通常只在可滾動(dòng)元素上呈現(xiàn)“滾動(dòng)窗口”中的內(nèi)容,以及已經(jīng)經(jīng)過(guò)該窗口的內(nèi)容,從而平衡好跳過(guò)渲染所節(jié)省的時(shí)間和內(nèi)存,以使?jié)L動(dòng)看起來(lái)更好看。瀏覽器可能會(huì)將此值作為信號(hào)來(lái)擴(kuò)展呈現(xiàn)的滾動(dòng)窗口周圍的內(nèi)容范圍,以便可以平滑地完成更長(zhǎng)/更快的滾動(dòng)。

contents

表示作者希望在不久的將來(lái)動(dòng)畫(huà)或更改元素內(nèi)容的某些內(nèi)容。 瀏覽器會(huì)提前針對(duì)此更改進(jìn)行適當(dāng)?shù)膬?yōu)化。

例如,瀏覽器經(jīng)常會(huì)隨著時(shí)間的推移“緩存”元素的渲染,因?yàn)榇蠖鄶?shù)東西不會(huì)經(jīng)常改變,或者只是改變它們的位置。 但是,如果元素確實(shí)定期更改其內(nèi)容,那么生成和維護(hù)此緩存就是浪費(fèi)時(shí)間。瀏覽器可能會(huì)將這個(gè)值作為一個(gè)信號(hào),在元素上不那么積極地緩存,或者根本避免緩存而只是不斷地從頭開(kāi)始重新渲染元素。

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

<custom-ident> 值(有關(guān)詳細(xì)信息,請(qǐng)參閱 <custom-ident> 條目)。 表示作者希望在不久的將來(lái)對(duì)元素上具有給定名稱的屬性進(jìn)行動(dòng)畫(huà)處理或更改。

例如,瀏覽器通常將設(shè)置有非初始值 transform 屬性的元素和其他元素區(qū)分開(kāi),可能將它們渲染到自己的“GPU 層”,或者使用其他機(jī)制來(lái)更容易的快速的進(jìn)行變換。瀏覽器可能會(huì)將 transform 的值作為一個(gè)信號(hào),表明它應(yīng)該在元素開(kāi)始轉(zhuǎn)換之前立即將元素提升到它自己的層,以避免重新渲染舊層和新層所涉及的任何延遲。

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

請(qǐng)注意,大多數(shù)屬性在指定時(shí)將不起作用,因?yàn)橛脩舸聿粫?huì)對(duì)大多數(shù)屬性的更改執(zhí)行任何特殊優(yōu)化。不過(guò),指定它們?nèi)匀皇前踩模m然它根本沒(méi)有效果。

注:感覺(jué)雖然命名為『自定義標(biāo)志』, 其實(shí)主要碰到的還是 css 預(yù)定義好的標(biāo)志,譬如 transform、opacity

例子

下面告訴瀏覽器期望元素的變換屬性發(fā)生變化,以便提前進(jìn)行適當(dāng)?shù)膬?yōu)化。

.el {
    will-change: transform;
}

上面的 will-change 聲明應(yīng)該通過(guò) JavaScript 添加,然后在更改結(jié)束后刪除或取消設(shè)置 (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;

使用小結(jié)

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

  • 不要將 will-change 應(yīng)用到太多元素上: 瀏覽器已經(jīng)盡力嘗試去優(yōu)化一切可以優(yōu)化的東西了。有一些更強(qiáng)力的優(yōu)化,如果與 will-change 結(jié)合在一起的話,有可能會(huì)消耗很多機(jī)器資源,如果過(guò)度使用的話,可能導(dǎo)致頁(yè)面響應(yīng)緩慢或者消耗非常多的資源。

  • 有節(jié)制地使用: 通常,當(dāng)元素恢復(fù)到初始狀態(tài)時(shí),瀏覽器會(huì)丟棄掉之前做的優(yōu)化工作。但是如果直接在樣式表中顯式聲明了 will-change 屬性,則表示目標(biāo)元素可能會(huì)經(jīng)常變化,瀏覽器會(huì)將優(yōu)化工作保存得比之前更久。所以最佳實(shí)踐是當(dāng)元素變化之前和之后通過(guò)腳本來(lái)切換 will-change 的值。

  • 不要過(guò)早應(yīng)用 will-change 優(yōu)化: 如果你的頁(yè)面在性能方面沒(méi)什么問(wèn)題,則不要添加 will-change 屬性來(lái)榨取一丁點(diǎn)的速度。 will-change 的設(shè)計(jì)初衷是作為最后的優(yōu)化手段,用來(lái)嘗試解決現(xiàn)有的性能問(wèn)題。它不應(yīng)該被用來(lái)預(yù)防性能問(wèn)題。過(guò)度使用 will-change 會(huì)導(dǎo)致大量的內(nèi)存占用,并會(huì)導(dǎo)致更復(fù)雜的渲染過(guò)程,因?yàn)闉g覽器會(huì)試圖準(zhǔn)備可能存在的變化過(guò)程。這會(huì)導(dǎo)致更嚴(yán)重的性能問(wèn)題。

  • 給它足夠的工作時(shí)間準(zhǔn)備,不要過(guò)遲應(yīng)用: 這個(gè)屬性是用來(lái)讓頁(yè)面開(kāi)發(fā)者告知瀏覽器哪些屬性可能會(huì)變化的。然后瀏覽器可以選擇在變化發(fā)生前提前去做一些優(yōu)化工作。所以給瀏覽器一點(diǎn)時(shí)間去真正做這些優(yōu)化工作是非常重要的。使用時(shí)需要嘗試去找到一些方法提前一定時(shí)間獲知元素可能發(fā)生的變化,然后為它加上 will-change 屬性。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“css中will-change屬性的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

css
AI