【问题标题】:How to use and how works CSS' will-change property?如何使用 CSS 的 will-change 属性以及如何工作?
【发布时间】:2021-11-24 10:25:55
【问题描述】:

我找到了 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 时,浏览器已经“知道”每个元素会发生什么,不是吗?

如果你能添加任何很好的例子来说明如何有效地使用它,我将不胜感激:)

【问题讨论】:

标签: css will-change


【解决方案1】:

我不会在此处复制粘贴整个 article,但这是一个 tl;dr 版本:

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

使用方法:

will-change: transform, opacity;

如何不使用它:

will-change: all;

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

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

在元素发生变化之前立即对元素设置 will-change 几乎没有影响。 (实际上可能比不设置更糟糕 一点也不。当你是什么时候,你可能会承担一个新层的成本 动画以前不适合新图层!)

【讨论】:

  • 此摘要中缺少的一个非常重要的部分位于 "Remove will-change After the Changes Are Done" 部分下,其中指出“浏览器为即将发生的更改所做的优化通常代价高昂,并且正如我们前面提到的,会占用机器的大部分资源。它所做的优化的通常浏览器行为是删除这些优化并尽快恢复正常行为。但是,will-change 会覆盖此行为,从而使优化保持的时间比浏览器要长得多。"
【解决方案2】:

我花了一些时间搜索will-change 属性的工作原理以及我们如何使用它。我希望,这将是有用的总结。谢谢大家的解答。

1.层黑客/空变换黑客

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

它是如何工作的?

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

2。再见黑客,欢迎“will-change:”

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

3.浏览器支持

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

4.如何正确使用它

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

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

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

例子:

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

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

您可以使用 JavaScript document.getElementById('my_element_id').style.willChange = off;轻松做到这一点

【讨论】:

  • “为未来的变化保留内存等资源”:足以作为使用它的理由。
  • @Tiyeb Bellal - 是的,如果您考虑 PC,但您还必须考虑移动设备...
  • 我认为使用纯css开启并使用javascript关闭不是一个好习惯,它包含不必要的耦合。
【解决方案3】:

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

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

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

基于W3C draft

will-change CSS 属性……允许作者提前通知 UA 他们可能会做出什么样的改变 元素。这允许 UA 优化他们处理元素的方式 提前,执行可能昂贵的工作,为 动画实际开始之前的动画。

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

此信息是关于 will-change 属性的from this excellent explanation。这篇文章有额外的例子,什么时候使用它很好,什么时候它没用甚至有害

【讨论】:

    【解决方案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

    【讨论】:

      【解决方案5】:

      感谢will-change CSS 属性,我们可以向浏览器声明我们打算更改元素的

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

      或删除特殊优化,使用值auto

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

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

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

      来自MDN web docs的备注:

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

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

      一个很好的附加资源,可以深入探讨这个主题:Everything You Need to Know About the CSS will-change Property

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

          【解决方案7】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-04
            相关资源
            最近更新 更多