搜索
首页web前端css教程深入了解css中的will-change属性

什么是css will-change属性?要怎么用?本篇文章就来带大家研究一下will-change属性,看看何时使用、如何使用以及如何更好的在css中设置will-change。

深入了解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

表示作者希望在不久的将来动画或更改元素内容的某些内容。 浏览器会提前针对此更改进行适当的优化。

例如,浏览器经常会随着时间的推移“缓存”元素的渲染,因为大多数东西不会经常改变,或者只是改变它们的位置。 但是,如果元素确实定期更改其内容,那么生成和维护此缓存就是浪费时间。浏览器可能会将这个值作为一个信号,在元素上不那么积极地缓存,或者根本避免缓存而只是不断地从头开始重新渲染元素。

e53daba18c25ef518ad73d82fe4f7af3 (028aa264268b1d80e0a56150adf879cc)

e53daba18c25ef518ad73d82fe4f7af3 值(有关详细信息,请参阅 e53daba18c25ef518ad73d82fe4f7af3 条目)。 表示作者希望在不久的将来对元素上具有给定名称的属性进行动画处理或更改。

例如,浏览器通常将设置有非初始值 transform 属性的元素和其他元素区分开,可能将它们渲染到自己的“GPU 层”,或者使用其他机制来更容易的快速的进行变换。浏览器可能会将 transform 的值作为一个信号,表明它应该在元素开始转换之前立即将元素提升到它自己的层,以避免重新渲染旧层和新层所涉及的任何延迟。

除了通常从 e53daba18c25ef518ad73d82fe4f7af3 中排除的关键字之外,e53daba18c25ef518ad73d82fe4f7af3 值不能是以下关键字之一:will-changenoneallautoscroll-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属性的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金社区。如有侵权,请联系admin@php.cn删除
我们如何标记Google字体并创建Goofonts.com我们如何标记Google字体并创建Goofonts.comApr 12, 2025 pm 12:02 PM

Goofonts是由开发人员和设计师丈夫签名的附带项目,它们都是版式的忠实拥护者。我们一直在标记Google

永恒的Web开发文章永恒的Web开发文章Apr 12, 2025 am 11:44 AM

Pavithra Kodmad向人们询问了他们认为是关于网络开发的一些最永恒的文章的建议

与部分元素的交易与部分元素的交易Apr 12, 2025 am 11:39 AM

同一天发表了两篇文章:

使用JavaScript API的状态练习GraphQl查询使用JavaScript API的状态练习GraphQl查询Apr 12, 2025 am 11:33 AM

学习如何构建GraphQL API可能具有挑战性。但是您可以学习如何在10分钟内使用GraphQL API!碰巧的是,我得到了完美的

组件级CMS组件级CMSApr 12, 2025 am 11:09 AM

当一个组件生活在数据查询居住在附近的数据查询的环境中时,视觉组件与

将类型设置在圆上...带偏移路径将类型设置在圆上...带偏移路径Apr 12, 2025 am 11:00 AM

这里是Yuanchuan的一些合法CSS骗局。有此CSS属性偏移路径。曾几何时,它被称为Motion-Path,然后被更名。我

'恢复”在CSS中有什么作用?'恢复”在CSS中有什么作用?Apr 12, 2025 am 10:59 AM

Miriam Suzanne在Mozilla开发人员的视频中解释了该主题。

现代恋人现代恋人Apr 12, 2025 am 10:58 AM

我喜欢这样的东西。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器