72

我找到了 CSS will-changeW3.org docsMDN docs属性(它已经在 Chrome 中运行,并且部分支持 Firefox 和 Opera),但我不确定它是如何工作的。有人对这个神秘的东西了解更多吗?

我刚刚读到它允许浏览器为将来计算元素做准备。我不想误解它。所以我有几个问题。

  1. 我应该将此属性添加到元素类还是它的悬停状态?

    .my-class{
        will-change: 'opacity, transform'
    }
    .my-class:hover{
        opacity: 0.5
    }
    .my-class:active{
        transform: rotate(5deg);
    }
    

    或者

    .my-class{
        ...
    }
    .my-class:hover{
        will-change: 'opacity'
        opacity: 0.5
    }
    .my-class:active{
        will-change: 'transform'
        transform: rotate(5deg);
    }
    
  2. 它如何提高浏览器的性能?理论上,当 CSS 被加载时,浏览器已经“知道”每个元素会发生什么,不是吗?

如果您可以添加任何说明如何有效使用它的好示例,我将不胜感激:)

4

7 回答 7

42

我不会在这里复制粘贴整篇文章,但这里有一个 tl;dr 版本:

指定您想要更改的确切内容可以让浏览器对这些特定更改所需的优化做出更好的决策。这显然是一种更好的方式来实现速度提升,而无需求助于黑客并迫使浏览器创建可能是必要的或不必要的图层。

如何使用它:

will-change: transform, opacity;

如何不使用它:

will-change: all;

.potato:hover {
  will-change: opacity;
  opacity:1;
}

在悬停时指定will-change无效:

在元素更改之前立即对其设置 will-change 几乎没有影响。(实际上可能比根本不设置更糟糕。当您制作动画的内容以前不适合新图层时,您可能会承担新图层的成本!)

于 2014-11-13T11:12:41.637 回答
27

我花了一些时间研究will-change财产如何运作以及我们如何使用它。我希望,这将是有用的总结。谢谢大家的回答。

1. Layers Hack / Null Transform Hack

在“远古时代”(比如 2 年前),有人发现您可以更快地绘制 CSS 动画。

它是如何工作的?

如果添加transform: translateZ(0)到 css 选择器,它将强制浏览器将带有此选择器的元素移动到新的合成器层。更重要的是,它将提高性能(在大多数情况下,使用 GPU 的能力而不是 CPU)在此处阅读更多内容

2. Bye Bye hacks,欢迎“will-change:”

或许,现在说再见 Layer Hack 还为时过早,但这一次很快就会到来。新属性will change出现在 CSS 规范中,将成为 layer hack 的伟大继承者。

3.浏览器支持

目前,它在 Chrome 和 Opera 中可用,Firefox 也部分支持。

4、如何正确使用

在完成动画实现之前,不要在 CSS 中的任何地方使用 will-change。只有这样你才能回到你的 CSS 并应用 will-change。更多的

这可能是你能得到的最有价值的建议。

在动作开始之前直接使用它是没有意义的,例如将它添加到:hover选择器的状态中。因为浏览器在更改发生之前不需要时间来准备优化。浏览器将需要大约。应用优化需要 200 毫秒,例如,will-change当父元素处于悬停状态时,最好添加到元素中。更多的

例子:

 .parent:hover .change{
     will-change: opacity;
 }
 .change:hover{
    opacity: .5;
 }

您需要非常谨慎地使用它。如果你想优化一切,结果将与预期相反。will-change强制浏览器保持优化打开,并为将来可能永远不会发生的更改保留内存等资源。will-change建议在不再需要时关闭,例如动画结束时。

您可以使用 JavaScript 轻松完成document.getElementById('my_element_id').style.willChange = off;

于 2014-11-16T17:07:52.850 回答
10

现在在 CSS 的帮助下,你可以做各种动画,有时这个动画会成为 CPU 的瓶颈。因此,与其在 CPU 上完成这项工作,不如使用 GPU 来完成这项任务。不久前,人们开始使用一种技巧来进行 2D 转换,方法如下:

.accelerate {
  -webkit-transform: translate3d(0, 0, 0);
}

这使浏览器认为它正在执行 3D 转换,并且由于所有 3D 转换都使用 GPU,这将卸载 CPU。这看起来很 hacky(因为实际上是这样),并且will-change属性将通过通知浏览器注意未来的变化来改变这一点,并相应地优化和分配内存。

基于W3C 草案

will-change CSS 属性……允许作者提前通知用户代理他们可能对元素进行哪些类型的更改。这允许 UA 提前优化他们处理元素的方式,在动画实际开始之前执行可能昂贵的动画准备工作。

使用的好主意 will-change是让浏览器提前知道可以对元素进行哪些更改。这允许浏览器提前进行适当的优化,从而加快渲染速度。

此信息取自有关财产的出色解释。will-change这篇文章有额外的例子,什么时候使用它很好,什么时候它没用甚至有害

于 2015-04-02T08:53:07.047 回答
4

我所知道的...

  1. 它是 translate-z:0 的替代方案。
  2. 我不知道悬停,但是最好在 JS 逐渐改变的属性上使用它,改变不透明度,滚动期间的位置等。
  3. 不应过度使用此属性,尤其是在手机、平板电脑上,在太多元素上使用此属性会导致性能问题。
  4. 当不再相关时,鼓励 JS 删除/关闭此属性。

因此,示例用法将在滚动的某个点应用它,使用 scrollTop:400,然后逐渐动画不透明度,并在让我们说 scrollTop:500,再次禁用 will-change。

资料来源:shoptalkshow 播客 - 他们提到这篇文章 - https://dev.opera.com/articles/css-will-change-property/ - 这可能是比我的帖子更好的信息来源:D

于 2014-11-13T11:10:50.930 回答
1

感谢will-changeCSS 属性,我们可以向浏览器声明我们改变元素的意图

  • contents,
  • scroll-position,
  • 各种标签属性,例如transformor opacity
  • 一次声明多个值:will-change: transform, opacity, top;

或使用 value 删除特殊优化auto

这允许浏览器安排使用GPU /硬件加速而不是标准CPU使用率。

但我们必须明智地使用它。我们需要:

  • 把它赋予一个会改变的元素,
  • 在更改发生之前尽早分配它,
  • 从已更改且不再存在的元素中删除它。

来自MDN 网络文档的注释

will-change旨在用作最后的手段,以尝试处理现有的性能问题。它不应该用于预测性能问题。

他们还提到,如果我们决定使用该will-change属性,我们不应该在 CSS 样式表中严格设置它,因为它可能会导致浏览器将优化保留在内存中的时间比需要的时间长得多……更好直接从 JavaScript 使用这个属性(也有一个例子)。

一个很好的附加资源来深入探索这个主题:关于 CSS will-change 属性你需要知道的一切

于 2020-06-22T17:24:36.183 回答
0

我正在使用 react-window 包,并且有一个“will-change:transform;” 外部 div 上的属性。该包根据滚动位置在可见视图中动态渲染大量数据的一部分,例如仅渲染 100000 长度列表的 10 项。如果没有 will-change 属性,滚动时列表将为空白。它在较慢的 cpu 上显示更好。

您可以在此处查看示例:react-window-fixed-size-list-vertical。打开开发者工具,在styles中取消勾选这个属性,在Performance选项卡中减慢cpu并快速滚动列表。渲染之间的列表空白

也有讨论。https://github.com/bvaughn/react-window/issues/47

于 2021-11-24T02:19:05.997 回答
-2

对我来说最好的解决方案:

transform : translate(calc(-50% + 0.5px), calc(-50% + 0.5px));

但是,这个解决方案在 ios safari 中的 calc 在固定位置会导致高电池消耗

于 2019-10-07T09:35:48.563 回答