CSS Will Change 模块 第一级

W3C 候选推荐草案,

更多关于本文档的详细信息
此版本:
https://www.w3.org/TR/2022/CRD-css-will-change-1-20220505/
最新发布版本:
https://www.w3.org/TR/css-will-change/
编辑草案:
https://drafts.csswg.org/css-will-change/
以前的版本:
历史记录:
https://www.w3.org/standards/history/css-will-change-1
实施报告:
https://wpt.fyi/results/css/css-will-change
测试套件:
https://wpt.fyi/results/css/css-will-change
反馈:
CSSWG 问题 存储库
编辑:
Tab Atkins Jr. (Google)
为此规范建议编辑:
GitHub 编辑器

摘要

本文档定义了 will-change CSS 属性,允许作者提前通知用户代理他们可能会对元素进行哪些类型的更改。这使用户代理能够提前优化处理该元素的方式,在动画实际开始之前执行可能代价昂贵的工作,为动画做好准备。

CSS 是一种描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上渲染的语言。

本文档的状态

本节描述了本文档在发布时的状态。当前 W3C 发布物的列表及此技术报告的最新修订版可在 W3C 技术报告索引 https://www.w3.org/TR/ 中找到。

本文档由 CSS 工作组 作为 候选推荐草案 使用 推荐标准轨道 发布。 发布为候选推荐草案不意味着 W3C 及其成员的认可。 候选推荐草案集成了工作组打算在后续的候选推荐快照中包含的来自以前的候选推荐的更改。

这是一份草案文档,可能会随时更新、替换或被其他文档取代。引用此文档为正在进行中的工作是不合适的。

请通过 在 GitHub 中提交问题(首选)的方式提供反馈,并在标题中包含规范代码 "css-will-change",如下所示: “[css-will-change] …反馈摘要…”。所有问题和评论都已 归档。 另外,可以将反馈发送到公开邮件列表 (已归档) www-style@w3.org

本文档受 2021年11月2日 W3C 流程文档 管辖。

本文档由一个根据 W3C 专利政策 运行的组织生成。 W3C 维护了 在本组织交付物中披露的任何专利的公共列表; 该页面还包括披露专利的说明。个人如知道认为包含 必要专利权要求 的专利,则必须根据 W3C 专利政策第 6 节 披露该信息。

1. 介绍

现代的 CSS 渲染器执行许多复杂的优化以快速、高效地渲染网页。 然而,实施这些优化往往需要不小的启动成本, 这可能会对页面的响应速度产生负面影响。

例如,当使用 CSS 3D 变换将元素移动到屏幕上的不同位置时, 元素及其内容可能会提升为一个“层”, 使其可以独立于页面的其他部分进行渲染,稍后再进行合成。 这将渲染内容与页面的其他部分隔离开来,确保当只有元素的变换在帧间发生变化时,不必重新渲染整个页面, 通常会提供显著的速度提升。

然而,将元素设置在新的层中是一个相对昂贵的操作, 这可能会延迟transform动画开始的时间,延迟时间长到足以被用户注意到。

本规范中定义的will-change属性允许作者提前声明哪些属性可能会在未来发生变化, 这样 UA 可以在需要之前设置适当的优化。 这种方式确保当实际的变化发生时, 页面可以快速响应。

1.1. 值的定义

本规范遵循CSS 属性定义惯例,并使用值定义语法,引用了 [CSS-VALUES-3]中的定义。 本规范未定义的值类型在 CSS 值与单位模块中定义 [CSS-VALUES-3]。 结合其他 CSS 模块可能扩展这些值类型的定义。

除了它们定义中列出的特定属性值之外, 本规范中定义的所有属性 还接受CSS-wide 关键词作为属性值。 为了可读性,它们没有被显式重复。

1.2. 正确使用 will-change

will-change属性, 像所有性能提示一样, 可能有些难以掌握如何“正确”使用, 尤其是它几乎不会产生作者可以直接检测到的效果。 然而,有一些简单的“应该做”和“不应该做”, 希望可以帮助开发者更好地直观了解如何正确使用 will-change

不要在过多属性或元素上滥用will-change

看到will-change时,常见的反应是认为像这样的代码是个好主意:

* { will-change: transform, opacity /* , ... */; }

毕竟,这告诉浏览器提前优化所有内容, 这肯定有好处,对吧?

错了。浏览器已经尽力优化所有内容。 明确地告诉它这样做并没有任何帮助, 事实上,可能会带来很大的危害; 与will-change 关联的某些强效优化会使用大量机器资源, 如果像这样过度使用,可能会导致页面变慢,甚至崩溃。

此外,will-change确实有一些副作用, 而且页面很可能不会想要在每个元素上都应用这些副作用。

谨慎在样式表中使用 will-change

在样式表中直接使用 will-change 暗示目标元素总是在几秒内发生变化。 这通常不是你真正想表达的含义; 相反,will-change通常应通过脚本在变化发生前后切换 (参见不要在已停止变化的元素上浪费资源)。 但是,在某些常见情况下,在样式表中直接使用 will-change是合适的。

例如, 在页面中指定will-change用于少数持久的 UI 元素, 这些元素应该对用户的操作做出快速响应:
body > .sidebar {
   will-change: transform;
   /* 将使用 'transform' 将侧边栏
      滑出用户请求的内容。 */
}

由于这是对少数元素的限制, 优化的应用频率较低并不会造成很大影响。

有时元素确实几乎不断改变属性。 它可能响应用户的鼠标移动, 或者定期执行某些操作触发动画。 在这种情况下,直接在样式表中声明will-change是合适的, 因为它准确描述了元素将定期/持续改变, 因此应保持优化。
.cats-flying-around-the-screen {
  will-change: left, top;
}

will-change足够的时间生效

另一个常见的不良模式是在开始动画或属性更改will-change帮助优化之前, 立即应用它。 不幸的是,大多数优化需要时间才能生效, 因此如果这么做,will-change几乎没有作用。 相反,找到某种方式至少稍微提前预测变化, 然后再设置 will-change

例如, 如果某个元素将在用户点击时发生变化, 在 hover 时设置will-change通常可以为优化的设置争取到至少 200 毫秒, 因为人类的反应时间相对较慢。 这可以通过脚本完成, 或者通过简单的 CSS 规则完成:
.element { transition: opacity .2s; opacity: 1; }
.element:hover { will-change: opacity; }
.element:active { opacity: .3; }

然而,如果效果发生在 hover 上,这样的规则是无效的。 在这种情况下,通常仍然可以找到一些方法在操作发生前进行预测。 例如,hover 祖先元素可能会提供足够的提前时间:

.element { transition: opacity .2s; opacity: 1; }
.container:hover > .element { will-change: opacity; }
.element:hover { opacity: .3; }

不要在已停止变化的元素上浪费资源

由于浏览器用于更改某些属性的优化代价较大, 浏览器通常会在正常情况下尽快移除这些优化并恢复到正常行为。 但是,will-change通常会覆盖这种行为, 使得优化持续的时间远长于浏览器通常情况下的时间。

因此,每当你将will-change添加到某个元素时, 尤其是通过脚本时, 不要忘记在元素完成变化后移除它, 以便浏览器可以恢复被优化占用的资源。

2. 提示未来行为: will-change 属性

名称: will-change
值: auto | <animateable-feature>#
初始值: auto
适用于: 所有元素
是否继承:
百分比: 不适用
计算值: 指定的值
规范顺序: 按语法顺序
动画类型: 不可动画化
<animateable-feature> = scroll-position | contents | <custom-ident>

will-change 属性为用户代理提供渲染提示, 告知作者预计将对元素进行哪些类型的更改。 这样,用户代理可以提前进行必要的优化,以平滑渲染这些更改, 避免当作者开始更改或动画化该功能时出现“卡顿”。

不同的浏览器可以以不同的方式使用 will-change 的信息, 即使是同一个浏览器在不同时间也可能以不同方式使用它。 例如,当指定 will-change: transform 时, 浏览器可能会将元素提升为其自己的“GPU层”, 但当声明此属性的元素数量过多时,可能会避免这样做, 以防耗尽GPU内存。

值有以下含义:

auto
表示没有特定的意图; 用户代理应应用其通常使用的任何启发式方法和优化。
scroll-position
表示作者预计在不久的将来会动画化或更改元素的滚动位置。

例如, 浏览器通常只渲染可滚动元素的“滚动窗口”中的内容, 以及窗口外的一部分内容, 在跳过渲染所节省的内存和时间与平滑滚动效果之间取得平衡。 浏览器可能会将此值作为信号,扩展滚动窗口周围已渲染内容的范围, 以便可以顺利地进行更长时间/更快的滚动。

contents
表示作者预计在不久的将来会动画化或更改元素内容的某些部分。
例如,浏览器经常随着时间推移“缓存”元素的渲染, 因为大多数东西不会经常更改, 或者只会更改它们的位置。 然而,如果一个元素的内容不断变化, 生成和维护该缓存是浪费时间。 浏览器可能会将此值作为信号,减少对该元素的缓存, 或完全避免缓存,而是持续从头渲染该元素。

此值主要用于帮助浏览器优化基于JS的内容动画, 这些动画每秒更改元素内容的多个方面。 当使用声明式动画时,浏览器已经自动执行这种优化。

注意: 此值基本上适用于声明它的元素的整个子树, 因为它表明浏览器应该计算出*任何*后代都可能以某种方式更改。 在文档结构较高的元素上使用它可能对页面性能非常不利; 尽量只在文档树中“底部”的元素上使用此值, 包含尽可能少的文档内容。

<custom-ident>
如果 <custom-ident> 与内置CSS属性的名称进行 ASCII不区分大小写 匹配, 它表示作者预计在不久的将来会动画化或更改元素上给定名称的属性。 如果给定的属性是简写, 则表示预计其展开后的所有长写属性也会更改。

例如, 设置 will-change: background; 等同于设置 will-change: background-image, background-position, ...,涵盖所有 background 展开的属性。

此处使用的 <custom-ident> 排除了关键字 will-changenoneallautoscroll-positioncontents, 以及通常从 <custom-ident> 中排除的关键字。

注意: 大多数属性在指定时不会产生任何效果, 因为用户代理不会为大多数属性的更改执行任何特殊优化。 不过,指定它们是 安全的; 它们只是不产生任何效果。

指定自定义属性不会产生任何效果, 这意味着通过自定义属性发生的效果 不会被视为以下规则中条件所述的任何非初始值导致的某些行为。

注意: 指定一个不被识别为属性的值是可以的; 它只是不产生任何效果。 这允许您安全地指定存在于某些用户代理中的 属性, 而不会对不知道该属性的旧版用户代理产生负面影响。

例如, 浏览器通常会以非常不同的方式处理设置了非初始值的 transform 的元素, 可能会将它们渲染到它们自己的“GPU层”, 或者使用其他机制,使快速执行 transform 可以实现的转换更容易。 浏览器可能会将 transform 值作为信号, 表示它应该立即将该元素提升为其自己的层, 在元素开始变换之前, 避免涉及重新渲染旧层和新层的延迟。

如果某个属性的非初始值会在元素上创建堆叠上下文, 则在 will-change 中指定该属性时, 必须在元素上创建堆叠上下文。

如果某个属性的非初始值会使该元素生成绝对定位元素的包含块, 则在 will-change 中指定该属性时, 必须使该元素生成绝对定位元素的包含块。

如果某个属性的非初始值会使该元素生成固定定位元素的包含块, 则在 will-change 中指定该属性时, 必须使该元素生成固定定位元素的包含块。

如果某个属性的非初始值会导致元素的渲染发生差异 (例如对文本使用不同的抗锯齿策略), 当该属性在 will-change 中被指定时, 用户代理应使用该备用渲染, 以避免属性最终更改时出现突然的渲染差异。

例如, 将 opacity 设置为 1 以外的任何值 都会在元素上创建堆叠上下文。 因此,设置 will-change: opacity 也会创建堆叠上下文, 即使 opacity 当前 仍等于 1

will-change 属性本身不会对指定的元素产生 直接 影响, 除了上述创建堆叠上下文和包含块的情况。 它只是对用户代理的渲染提示, 允许用户代理在某些类型的更改实际发生之前, 设置可能会非常昂贵的优化。

3. 安全性考量

本文件未提出任何安全性问题

4. 隐私考量

本文件未提出任何隐私问题

5. 致谢

感谢 Benoit Girard 最早提出了 will-animate 属性, 并完成了大量初期设计工作。

6. 更改

2015年12月3日CR版本起的更改:

2014年4月29日工作草案版本起的更改:

规范符合性

文档约定

规范要求通过描述性断言和RFC 2119术语的组合进行表达。关键词“必须(MUST)”、“禁止(MUST NOT)”、 “必要(REQUIRED)”、“应当(SHALL)”、“不得(SHALL NOT)”、“应该(SHOULD)”、 “不应该(SHOULD NOT)”、“推荐(RECOMMENDED)”、“可以(MAY)”和“可选(OPTIONAL)”在本文件的规范性部分中按照RFC 2119的定义解释。 然而,为了易于阅读,这些词语在本规范中不会全部大写。

本规范的所有文本都是规范性的,除非明确标注为非规范部分、示例或注释。[RFC2119]

本规范中的示例以“例如(for example)”开头,或通过使用class="example"从规范文本中分开,如下所示:

这是一个信息性示例。

信息性注释以“注:”开头,并通过class="note"从规范文本中分开,如下所示:

注:这是一个信息性注释。

建议性内容是规范性部分,使用 <strong class="advisement"> 样式来突出显示,如下所示: 用户代理必须(MUST)提供无障碍的替代方案。

符合性类别

本规范的符合性定义为三种符合性类别:

样式表
CSS样式表
渲染器
解释样式表语义并渲染使用它们的文档的用户代理(UA)。
创作工具
编写样式表的用户代理(UA)。

样式表符合本规范的条件是,如果其所有使用本模块定义的语法的声明,均符合通用CSS语法以及本模块每个功能定义的语法。

渲染器符合本规范的条件是,除了按照相关规范解释样式表外,还必须正确解析并支持本规范定义的所有功能,并相应地渲染文档。 然而,因设备限制导致的用户代理无法正确渲染文档并不会使其不符合规范。(例如,用户代理并不需要在单色显示器上渲染颜色。)

创作工具符合本规范的条件是,它编写的样式表在语法上必须符合通用CSS语法以及本模块中每个功能的语法, 并满足本模块中描述的样式表的其他符合性要求。

部分实现

为了让作者能够利用向前兼容的解析规则来指定后备值,CSS渲染器必须将任何没有可用支持级别的 at规则、属性、属性值、关键字和其他语法结构视为无效,并且适当忽略它们。 特别是,用户代理不得选择性地忽略不支持的组件值而保留支持的值在同一个多值属性声明中: 如果任何值被视为无效(因为不支持的值必须如此),CSS要求整个声明被忽略。

不稳定和专有功能的实现

为了避免与未来稳定的CSS功能冲突,CSS工作组建议在实现不稳定功能和专有扩展时,遵循最佳实践

非实验性实现

一旦规范达到候选推荐(CR)阶段,便可以进行非实验性实现,开发者应发布符合规范且经过验证的无前缀实现。

为了建立和维护CSS在不同实现之间的互操作性,CSS工作组请求非实验性CSS渲染器在发布任何无前缀的CSS功能实现之前,向W3C提交实现报告(以及必要时提供实现报告中使用的测试案例)。提交给W3C的测试案例需经过CSS工作组的审查和修改。

关于提交测试案例和实现报告的更多信息,请参阅CSS工作组网站:https://www.w3.org/Style/CSS/Test/。问题可发送至 public-css-testsuite@w3.org

CR退出标准

本规范要推进到提案推荐(Proposed Recommendation)阶段,必须至少有两个独立的、互操作性良好的实现,并且每个功能至少有两套独立实现。每个功能可以由不同的产品实现,不要求所有功能由单个产品实现。以下是相关术语的定义:

独立
每个实现必须由不同的开发方开发,且不能共享、重用或基于其他合格实现的代码。与本规范实现无关的代码部分可不受此要求限制。
互操作性
在官方CSS测试套件中通过相应的测试,或者如果实现不是网页浏览器,则通过等效测试。所有相关测试应有等效测试,以便声称互操作性时使用。如果某用户代理(UA)声称互操作性,则必须有一个或多个其他UA通过相同测试来证明互操作性。这些等效测试必须公开,以便同行评审。
实现
用户代理(UA),符合以下条件:
  1. 实现了本规范。
  2. 对公众开放,可能是正式发布的产品,也可能是其他公开发布的版本(例如测试版、预览版或“夜间构建”)。
  3. 不应是专门为通过测试套件而设计的实验版本,且该版本不应用于正常使用。

本规范将保持候选推荐(CR)状态至少六个月。

索引

由本规范定义的术语

参考文献中定义的术语

参考文献

规范性参考文献

[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2019年6月6日. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2021年12月16日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS2]
Bert Bos; et al. 层叠样式表第2级修订版 (CSS 2.1) 规范. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. 现行标准. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. 在RFC中使用的关键词表示要求等级. 1997年3月. 最佳现行做法. URL: https://datatracker.ietf.org/doc/html/rfc2119

参考性参考文献

[CSS-BACKGROUNDS-3]
Bert Bos; Elika Etemad; Brad Kemper. CSS 背景和边框模块第3级. 2021年7月26日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS 颜色模块第4级. 2021年12月15日. WD. URL: https://www.w3.org/TR/css-color-4/
[CSS-TRANSFORMS-1]
Simon Fraser; 等. CSS 变换模块第1级. 2019年2月14日. CR. URL: https://www.w3.org/TR/css-transforms-1/

属性索引

名称 初始值 应用于 继承性 百分比 动画类型 语法顺序 计算值
will-change auto | <animateable-feature># auto 所有元素 不适用 不可动画 按语法顺序 指定值