CSS `will-change` - 如何使用它,它是如何工作的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26907265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CSS `will-change` - how to use it, how it works
提问by LJ Wadowski
I found CSS will-change
W3.org docs, MDN docsproperty (which already works in Chrome and is partiali supported by Firefox and Opera) but I'm not really sure how it works.
Does anybody know something more about this mysterious thing?
我找到了 CSS will-change
W3.org docs,MDN docs属性(它已经在 Chrome 中工作并且被 Firefox 和 Opera 部分支持)但我不确定它是如何工作的。有人知道更多关于这个神秘事物的事情吗?
I have just read that it allows browser to prepare for calculation over the element in the future. I don't want to misunderstand it. So I have a few questions.
我刚刚读到它允许浏览器为将来计算元素做准备。我不想误解它。所以我有几个问题。
Should I add this property to the element class or its hover state?
.my-class{ will-change: 'opacity, transform' } .my-class:hover{ opacity: 0.5 } .my-class:active{ transform: rotate(5deg); }
OR
.my-class{ ... } .my-class:hover{ will-change: 'opacity' opacity: 0.5 } .my-class:active{ will-change: 'transform' transform: rotate(5deg); }
How can it increase a browser performance? Theoretically, when CSS is loaded, the browser already "knows" what will happen with each element, doesn't it?
我应该将此属性添加到元素类或其悬停状态吗?
.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 时,浏览器已经“知道”每个元素会发生什么,不是吗?
If you can add any good example illustrating how to use it efficiently, I will be grateful :)
如果你能添加任何好的例子来说明如何有效地使用它,我将不胜感激:)
采纳答案by Patsy Issa
I won't copy paste the entire articlehere but here's a tl;dr version:
我不会在这里复制粘贴整篇文章,但这里有一个 tl;dr 版本:
Specifying what exactly you want to change allows the browser to make better decisions about the optimizations that it needs to make for these particular changes. This is obviously a better way to achieve a speed boost without resorting to hacks and forcing the browser into layer creations that may or may not be necessary or useful.
指定您想要更改的确切内容可以让浏览器做出更好的决策,以便针对这些特定更改进行优化。这显然是实现速度提升的更好方法,而无需求助于黑客并强制浏览器创建可能或可能不需要或有用的图层。
How to use it:
如何使用它:
will-change: transform, opacity;
How not to use it:
如何不使用它:
will-change: all;
.potato:hover {
will-change: opacity;
opacity:1;
}
Specifying will-change
on hover has no effect:
will-change
在悬停时指定无效:
Setting will-change on an element immediately before it changes has little to no effect. (It might actually be worse than not setting it at all. You could incur the cost of a new layer when what you're animating wouldn't have previously qualified for a new layer!)
在元素更改之前立即在元素上设置 will-change 几乎没有效果。(这实际上可能比根本不设置更糟糕。如果您正在制作动画的内容以前不符合新图层的条件,您可能会产生新图层的成本!)
回答by LJ Wadowski
I spent some time on searching how will-change
property works and how we use it. I hope, it will be useful summary. Thanks everybody for answers.
我花了一些时间研究will-change
财产如何运作以及我们如何使用它。我希望,这将是有用的总结。谢谢大家的回答。
1. Layers Hack / Null Transform Hack
1. Layers Hack / Null Transform Hack
In 'ancient times' (like 2 years ago) somebody discovered that you can draw your CSS animation faster.
在“远古时代”(例如 2 年前)有人发现您可以更快地绘制 CSS 动画。
How does it work?
它是如何工作的?
If you add transform: translateZ(0)
to a css selector, it will force a browser to move the element with this selector to the new compositor layer. What is more, it will increase performance (in most situations, use powers of GPU instead CPU) read more here.
如果添加transform: translateZ(0)
到 css 选择器,它将强制浏览器将带有此选择器的元素移动到新的合成器层。更重要的是,它会提高性能(在大多数情况下,使用 GPU 的力量代替 CPU)在这里阅读更多。
2. Bye Bye hacks, welcome "will-change:"
2. Bye Bye hacks,欢迎“will-change:”
Probably, it's too early to say bye bye to Layer Hack, but this time will come shortly.
The new property will change
appeared in specs of CSS and will be a great successor of layer hack.
或许,现在说再见 Layer Hack 还为时过早,但这次很快就会到来。新属性will change
出现在 CSS 规范中,将成为 layer hack 的伟大继承者。
3. Browser support
3.浏览器支持
For now, it's available in Chrome and Opera and partially supported by Firefox as well.
目前,它在 Chrome 和 Opera 中可用,Firefox 也部分支持。
4. How to use it properly
4.如何正确使用
Don't use will-change anywhere in your CSS until after you will complete implementing your animations. Only then should you go back to your CSS and apply will-change. More
在完成动画实现之前,不要在 CSS 的任何地方使用 will-change。只有这样你才应该回到你的 CSS 并应用 will-change。更多的
This is probably the most valuable advice that you can get.
这可能是你能得到的最有价值的建议。
There is no point to use it straight before an action begins by e.g. adding it to the :hover
state of a selector. Because browser will not have required time to prepare optimization before change occurrence. Browser will need approx. 200ms to apply optimization, so for example it is better to add will-change
to a element when a parent element is on hover state. More
在动作开始之前直接使用它是没有意义的,例如将它添加到:hover
选择器的状态。因为浏览器在更改发生之前不需要时间来准备优化。浏览器将需要大约。应用优化需要 200 毫秒,例如,最好will-change
在父元素处于悬停状态时添加到元素。更多的
Example:
例子:
.parent:hover .change{
will-change: opacity;
}
.change:hover{
opacity: .5;
}
You need to use it really sparingly. If you want to optimize everything, the results will be opposite than expected ones. will-change
forces browser to keep optimization turned on and reserve resources like memory for changes in the future which may never happen. It is recommended to turn off will-change
afterwards, when it is not necessary anymore e.g. when the animation is finished.
你需要非常谨慎地使用它。如果您想优化所有内容,结果将与预期相反。will-change
强制浏览器保持优化并保留内存等资源以备将来可能永远不会发生的更改。建议will-change
之后关闭,当不再需要时,例如当动画完成时。
You can do it easily using JavaScript document.getElementById('my_element_id').style.willChange = off;
您可以使用 JavaScript 轻松完成 document.getElementById('my_element_id').style.willChange = off;
回答by Salvador Dali
Now with the help of CSS you can do various of animations, and sometimes this animation becomes a bottleneck for a CPU. So instead of doing this job on a CPU, it would be nice to use GPU for this task. And not so long ago people started to use a trick to do this for a 2D transformation by doing something like:
现在在 CSS 的帮助下你可以做各种动画,有时这个动画会成为 CPU 的瓶颈。因此,与其在 CPU 上完成这项工作,不如使用 GPU 来完成这项任务。不久前,人们开始使用一种技巧来进行 2D 转换,方法如下:
.accelerate {
-webkit-transform: translate3d(0, 0, 0);
}
This made a browser think that it is doing a 3D transformation, and because all 3D transformations are using GPU, this will offload CPU. This looks hacky (because in fact it is) and will-change
property is going to change this by informing the browser to look out for changes in the future, and optimize and allocate memory accordingly.
这让浏览器认为它正在执行 3D 转换,并且因为所有 3D 转换都使用 GPU,这将卸载 CPU。这看起来很糟糕(因为实际上是这样)并且will-change
属性将通过通知浏览器注意未来的变化来改变这一点,并相应地优化和分配内存。
Based on W3C draft,
基于W3C 草案,
The will-change CSS property … allows an author to inform the UA ahead of time of what kinds of changes they are likely to make to an element. This allows the UA to optimize how they handle the element ahead of time, performing potentially-expensive work preparing for an animation before the animation actually begins.
will-change CSS 属性……允许作者提前通知 UA 他们可能对元素进行哪些类型的更改。这允许 UA 提前优化他们处理元素的方式,在动画实际开始之前执行可能昂贵的准备动画的工作。
Good idea to usewill-change
is to let the browser know in advance what changes on an element can be expected. This allows the browser to make the proper optimizations in advance, which leads to quicker rendering.
使用的好主意will-change
是让浏览器提前知道元素会发生哪些变化。这允许浏览器提前进行适当的优化,从而加快渲染速度。
This information was taken from this excellent explanationabout will-change
property. The article has additional example when it is nice to use it and when it is useless or even detrimental
这些信息取自这个关于will-change
财产的极好解释。这篇文章有额外的例子,什么时候用它很好,什么时候它没用甚至有害
回答by Martin Malinda
As far as I know...
据我所知...
- It is an alternative for translate-z:0.
- I dont know about hover, but afaik its best to use it on properties that are being changed gradually by JS, changing opacity, position during scrolling etc.
- This property shouldnt be overused, especially on phones, tablets, using this on too many elements can cause performance issues.
- It is encouraged to remove/turn-off this property by JS when it is no longer relevant.
- 它是 translate-z:0 的替代方案。
- 我不知道悬停,但 afaik 最好在 JS 逐渐改变的属性上使用它,改变不透明度,滚动期间的位置等。
- 不应过度使用此属性,尤其是在手机、平板电脑上,在过多元素上使用此属性会导致性能问题。
- 当它不再相关时,鼓励 JS 删除/关闭此属性。
So example usage would be applying that at some point of scroll, with scrollTop:400, then gradually animate opacity and at lets say scrollTop:500, disable will-change again.
因此,示例用法是在滚动的某个点应用它,使用 scrollTop:400,然后逐渐设置不透明度动画,然后说 scrollTop:500,再次禁用 will-change。
Source: shoptalkshow podcast - they mention this article - https://dev.opera.com/articles/css-will-change-property/- which is probably better source of info than my post :D
来源:shoptalkshow 播客 - 他们提到了这篇文章 - https://dev.opera.com/articles/css-will-change-property/- 这可能是比我的帖子更好的信息来源:D
回答by Павел Сайк
The best solution for me:
对我来说最好的解决方案:
transform : translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
But, this solution has trouble with calc in ios safari in a fixed position can cause high battery consumption
但是,此解决方案在 ios safari 中固定位置的 calc 有问题会导致电池消耗高