我发现CSS will-change
W3.org 文档,MDN文档属性(已经在Chrome中工作并且部分受Firefox和Opera支持),但我不确定它是如何工作的。有没有人知道更多关于这个神秘的东西?
我刚刚读到它允许浏览器为将来对元素的计算做准备。我不想误解它。所以我有几个问题。
-
我应该将此属性添加到元素类或其悬停状态吗?
.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); }
-
它如何提高浏览器性能?从理论上讲,当加载CSS时,浏览器已经"知道"每个元素会发生什么,不是吗?
如果您能添加任何说明如何有效使用它的好例子,我将不胜感激:)
我不会在这里复制粘贴整篇文章,但这里有一个 tl;dr 版本:
通过指定要更改的内容,浏览器可以更好地决定需要针对这些特定更改进行的优化。这显然是实现速度提升的更好方法,而无需诉诸黑客并迫使浏览器进入可能必要也可能不必要或有用的层创建。
如何使用它:
will-change: transform, opacity;
如何不使用它:
will-change: all;
.potato:hover {
will-change: opacity;
opacity:1;
}
在悬停时指定will-change
不起作用:
在元素更改之前立即设置将更改具有 几乎没有效果。(这实际上可能比不设置它更糟糕 完全。当您是什么时,您可能会产生新层的成本 动画以前没有资格获得新图层!
我花了一些时间来搜索will-change
属性是如何工作的以及我们如何使用它。我希望,这将是有益的总结。谢谢大家的回答。
1. 层黑客/空转换黑客
在"古代"(如2年前),有人发现您可以更快地绘制CSS动画。
它是如何工作的?
如果将transform: translateZ(0)
添加到 css 选择器,它将强制浏览器使用此选择器将元素移动到新的合成器层。更重要的是,它将提高性能(在大多数情况下,使用 GPU 而不是 CPU 的功能)在此处阅读更多内容。
2.再见黑客,欢迎"意志改变:"
也许,现在告别Layer Hack还为时过早,但这个时候很快就会到来。新属性will change
出现在CSS的规范中,将成为Layer hack的伟大继承者。
3. 浏览器支持
目前,它在Chrome和Opera中可用,Firefox也部分支持。
4.如何正确使用它
不要在 CSS 中的任何位置使用 will-change,直到你之后 完成动画的实现。只有这样,你才应该回到 您的 CSS 和应用将更改。更多
这可能是你能得到的最有价值的建议。
在操作开始之前直接使用它是没有意义的,例如将其添加到选择器的: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;
轻松完成此操作
现在在CSS的帮助下,您可以执行各种动画,有时此动画会成为CPU的瓶颈。因此,与其在 CPU 上执行此工作,不如使用 GPU 来完成此任务。不久前,人们开始使用一个技巧来做2D转换,比如:
.accelerate {
-webkit-transform: translate3d(0, 0, 0);
}
这让浏览器认为它正在进行 3D 转换,并且由于所有 3D 转换都使用 GPU,这将卸载 CPU。这看起来很笨拙(因为事实上确实如此),will-change
属性将通过通知浏览器注意将来的变化来改变这一点,并相应地优化和分配内存。
基于 W3C 草案,
将更改 CSS 属性...允许作者提前通知 UA 他们可能对 元素。这允许 UA 优化他们处理元素的方式 提前执行可能昂贵的工作,为准备 动画实际开始之前动画。
使用will-change
的好主意是提前让浏览器知道元素上可以发生哪些更改。这允许浏览器提前进行适当的优化,从而加快渲染速度。
这些信息取自will-change
财产的出色解释。这篇文章有额外的例子,当使用它很好,当它无用甚至有害时
我所知...
- 它是 translate-z:0 的替代方法。
- 我不知道悬停,但最好在 JS 逐渐更改的属性上使用它,在滚动过程中更改不透明度、位置等。
- 此属性不应过度使用,尤其是在手机、平板电脑上,在太多情况下使用它 元素可能会导致性能问题。
- 当此属性不再相关时,建议通过 JS 删除/关闭此属性。
因此,示例用法是在滚动的某个点应用它,使用 scrollTop:400,然后逐渐对不透明度进行动画处理,并在 scrollTop:500 时禁用将再次更改。
来源:shoptalkshow 播客 - 他们提到了这篇文章 - https://dev.opera.com/articles/css-will-change-property/- 这可能是比我的帖子更好的信息来源:D
多亏will-change
CSS 属性,我们可以向浏览器声明我们更改元素的意图:
-
contents
, -
scroll-position
, - 各种标签属性,如
transform
或opacity
, - 一次声明多个值:
will-change: transform, opacity, top;
或使用值 auto
删除特殊优化。
这允许浏览器计划使用 GPU/硬件加速而不是标准 CPU 使用率。
但我们必须明智地使用它。我们需要:
- 将其提供给将要更改的元素,
- 在更改发生之前尽早分配它,
- 将其从已更改且不再更改的元素中删除。
来自 MDN Web 文档的说明:
will-change
旨在用作最后的手段,以尝试处理现有的性能问题。它不应用于预测性能问题。
他们还提到,如果我们决定使用 will-change
属性,我们不应该在 CSS 样式表中严格设置它,因为它可能会导致浏览器将优化保留在内存中的时间比需要的时间长得多......最好直接从 JavaScript 使用此属性(还有一个示例)。
很好的附加资源,可以更深入地探讨这个主题:你需要知道的关于CSS将改变属性的所有信息。
我正在使用 react-window 包,并且在外部div 上有一个"will-change: transform;"属性。包根据滚动位置在可见视图中动态呈现大型数据集的一部分,例如,仅呈现 100000 长度列表中的 10 个项目。如果没有 will-change 属性,则滚动时列表将为空。它在较慢的CPU上显示得更好。
你可以在这里看到这个例子:react-window-fixed-size-list-vertical。打开开发人员工具,在样式中取消选中此属性,在"性能"选项卡中减慢 cpu 的速度并快速滚动列表。
还有一个讨论.https://github.com/bvaughn/react-window/issues/47
对我来说最好的解决方案:
transform : translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
但是,此解决方案在固定位置的ios safari中的计算出现问题,可能会导致高电池消耗