In this article, we’re going to take a look at the CSS will-change
property, what it is, when and how to use it, and how not to use it. There’s quite a bit of technical documentation available with regards to will-change
, so I’ll reference a lot of those resources throughout this article, and compile them in a list at the end. This article will serve as an overview of the important parts with some quick examples.
在本文中,我们将了解CSS will-change
属性 ,它的含义,何时以及如何使用它以及如何不使用它。 有很多关于will-change
的技术文档,因此我将在本文中引用很多这些资源,并在最后列出它们。 本文将通过一些快速示例来概述重要部分。
Today many front-end developers are leveraging CSS3 transitions, transforms, and animations to add a new layer of application interactivity that was previously left up to JavaScript libraries or Flash. Now we’re able to perform smooth and beautiful animations with minimal CSS. If you’ve been experimenting with and utilising these CSS3 properties, you’ve likely come across the terms CPU, GPU, and hardware acceleration. Let’s break these terms down quickly:
今天,许多前端开发人员正在利用CSS3过渡,转换和动画来添加应用程序交互性的新层,而该层以前是由JavaScript库或Flash保留的。 现在,我们可以使用最少CSS来执行流畅而精美的动画。 如果您一直在尝试和利用这些CSS3属性,则可能会遇到CPU,GPU和硬件加速这两个术语。 让我们快速分解这些术语:
How does this improve the performance and quality of animations? Well, for starters, on WebKit-based browsers, we may often see a flicker when performing some CSS operations, namely 2D transforms and animations. In the past, we’ve gotten around this by tricking the browser a little. We would make the browser thing it was performing a 3D transform, thus offloading the operation onto the GPU. That’s because 3D transforms are automatically moved there. That leads us to some trickery like this:
这如何改善动画的性能和质量? 好吧,对于初学者来说,在基于WebKit的浏览器上,执行一些CSS操作(即2D变换和动画)时,我们经常会出现闪烁。 过去,我们通过欺骗浏览器来解决这个问题。 我们可以让浏览器执行3D转换,从而将操作转移到GPU上。 那是因为3D变换会自动移动到那里。 这使我们陷入了一些骗局:
.accelerate {
-webkit-transform: translate3d(0, 0, 0);
}
There are some similar tricks, but for the most part, this covers us. However, this is a hack, and this is where the will-change
property will help us out greatly, when used correctly. Let’s investigate.
也有一些类似的技巧,但是在大多数情况下,这涵盖了我们。 但是,这是一个hack,如果正确使用, will-change
属性将在很大程度上帮助我们。 让我们调查一下。
will-change
? (What is will-change
?)According to the W3C editor’s 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可以提前优化他们如何处理元素,在动画开始之前执行可能昂贵的工作以准备动画。
This means that instead of forcing our transforms onto the GPU via a 3D transform hack, we can now use a dedicated property to inform the browser to look out for changes in the future, and optimise and allocate memory accordingly. Sounds pretty neat, right? Before we get all excited though, we need to understand how to use will-change
.
这意味着,我们现在可以使用专用属性来通知浏览器,以防止将来发生更改,并相应地优化和分配内存,而不是通过3D转换黑客将转换强制到GPU。 听起来很整洁,对不对? 但是,在让我们兴奋之前,我们需要了解如何使用will-change
。
will-change
如何使用? (How is will-change
used?)The will-change
property is only effective when used at a certain time. We can’t apply something like will-change: transform
to an already-transforming element — it just doesn’t make sense. Sara Soueidan discusses this in fantastic detail on the Opera blog, so be sure to check that out, but the key points to note are these:
will-change
属性仅在特定时间使用时才有效。 我们不能应用诸如will-change: transform
类的东西will-change: transform
为已经变形的元素-只是没有意义。 Sara Soueidan在Opera博客上对此进行了详尽的讨论 ,因此请务必检查一下,但是要注意的关键点是:
We’re interested in using this property to let the browser know ahead of time what changes on an element can be expected.
我们感兴趣的是使用此属性让浏览器提前知道可以预期的元素变化。
With the above points in mind, let’s look at an example that will have no effect:
考虑到以上几点,让我们看一个无效的示例:
.will-change:active {
will-change: transform;
transition: transform 0.3s;
transform: scale(1.5);
}
Here, a change is already taking place by the time we inform the browser, totally cancelling out the whole point of the will-change
property. If we want the browser to know ahead of time when to expect changes, we will have to inform it at the right moment.
在此,当我们通知浏览器时,已经在进行更改,从而完全抵消了will-change
属性的全部内容。 如果我们希望浏览器提前知道什么时候会发生更改,则必须在适当的时候通知它。
For an element to achieve an active
state, it must first be hovered. We can then do something like this:
为了使元素达到active
状态,必须首先将其悬停。 然后,我们可以执行以下操作:
.will-change {
transition: transform 0.3s;
}
.will-change:hover {
will-change: transform;
}
.will-change:active {
transform: scale(1.5);
}
This small example gives us some insight into the thought process needed to properly use the will-change
property. But before we continue with more examples, we need to be aware of some important considerations.
这个小例子使我们对适当使用will-change
特性所需的思考过程有了一些见识。 但是在继续介绍更多示例之前,我们需要了解一些重要的考虑因素。
Browsers, by nature, try their absolute best to optimise and be prepared for changes. Browsers will remove certain optimizations as soon as they can in order to free up memory. Using the will-change
property directly on an element, though, insists to the browser that the element in question is always very close to a change. This forces the browser to maintain optimizations, thus increasing memory consumption. With that in mind, we need to have a way of adding and removing the will-change
property at the right times. The first example does this for us, because the property will only get added on hover. But what if we wanted the transform to actually occur on hover? You might be tempted to do this:
本质上,浏览器会尽最大努力优化并为更改做好准备。 浏览器将尽快删除某些优化,以释放内存。 但是,直接在元素上使用will-change
属性will-change
向浏览器要求,所讨论的元素总是非常接近更改。 这迫使浏览器保持优化,从而增加了内存消耗。 考虑到这一点,我们需要一种在正确的时间添加和删除will-change
属性的方法。 第一个示例为我们完成了此操作,因为该属性仅在悬停时添加。 但是,如果我们希望转换实际上在悬停时发生呢? 您可能会这样做:
.will-change {
will-change: transform;
transition: transform 0.3s;
}
.will-change:hover {
transform: scale(1.5);
}
This will result in an increase in memory consumption though, because we’re forcing the browser into thinking that the element is close to being changed at all times. We can get around this by instead looking for a hover event on the parent container:
但是,这将导致内存消耗增加,因为我们迫使浏览器认为该元素几乎随时都在被更改。 我们可以通过在父容器上寻找一个悬停事件来解决此问题:
.will-change-parent:hover .will-change {
will-change: transform;
}
.will-change {
transition: transform 0.3s;
}
.will-change:hover {
transform: scale(1.5);
}
This adds the optimization when the mouse enters the parent container, and removes it when the mouse leaves. It also, however, implies that every time the mouse enters the parent container, the browser can expect a change on the element. This isn’t necessarily the case, and presents a perfectly clear example of how easy it is to abuse this property.
这将在鼠标进入父容器时添加优化,并在鼠标离开时将其删除。 但是,这也意味着每次鼠标进入父容器时,浏览器都可以期望对该元素进行更改。 不一定是这种情况,并且提供了一个完全清楚的例子来说明滥用此属性有多么容易。
Building a full-screen slideshow or CSS flip-book of some sort is an example of when direct application could work. Slides will always need to be changed, so doing something like the following might be suitable:
构建某种形式的全屏幻灯片或CSS翻书是直接应用程序何时可以工作的一个示例。 总是需要更改幻灯片,因此执行以下操作可能是合适的:
.slide {
will-change: transform;
}
will-change
(Always Remove will-change
)Always remember to remove the will-change
property when you’re finished using it. As I mentioned above, browser optimizations are a costly process and so when used poorly they can have adverse effects. We can handle this with JavaScript, and we’ll reference a script from MDN to build a rough case example. Imagine we have an element with a class of element
, and when we click on it, it gets transformed. Our CSS could look like this:
使用完后,请务必记得删除will-change
属性。 如上所述,浏览器优化是一个昂贵的过程,因此,如果使用不当,可能会产生不利影响。 我们可以使用JavaScript进行处理,我们将引用MDN中的脚本来构建一个粗略的示例。 想象一下,我们有一个带有class element
,当我们单击它时,它就被转换了。 我们CSS可能如下所示:
.element {
transition: transform 0.5s;
}
.element.clicked {
transform: scale(1.5);
}
If we want to notify the browser to prepare optimizations for a change that’s about to happen in response to a click on an element, we can do something like this:
如果我们想通知浏览器为即将发生的更改做优化,以响应单击元素,我们可以执行以下操作:
var el = document.querySelector('.element');
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);
function hintBrowser() {
this.style.willChange = 'transform';
}
function removeHint() {
this.style.willChange = 'auto';
}
Of course, you’d need to include the necessary JavaScript to add the correct clicked
class when the element is actually clicked, but the above script should give you some insight into how to prepare the browser for changes, and to release memory once the changes are complete. When the mouse enters the element, the will-change
property is added. When it’s clicked and the transform occurs (by your corresponding script), animation events will be sent out. On animationEnd
we’ll remove the will-change
property, freeing up memory once again.
当然,您需要包括必要JavaScript以在实际单击元素时添加正确的clicked
类,但是上述脚本应该使您对如何为更改做准备并在更改后释放内存有一些了解。完成。 当鼠标进入该元素时, will-change
添加will-change
属性。 单击它并进行转换时(通过相应的脚本),将发送动画事件。 在animationEnd
我们将删除will-change
属性,再次释放内存。
The will-change
property is fairly new, and is currently supported by the following browsers according to Can I Use:
will-change
属性是一个相当新的属性,根据“我可以使用” ,以下浏览器当前支持该属性:
Internet Explorer is the only major missing browser and will-change
is listed as under consideration as of this writing.
Internet Explorer是唯一缺少的主要浏览器, 在撰写本文时,正在考虑 will-change
。
The CSS will-change
property can do just as much good as it can harm. This statement isn’t meant to deter you from using it, but acts as an advisory. There’s no reason to not consider it in your modern application builds, but just be mindful of all the potential issues I’ve pointed out. I hope you gained some insight into the wild world of browser optimizations, and can take this knowledge forward into your future projects.
CSS的will-change
属性可以尽其所能。 此声明并非要阻止您使用它,而只是作为建议。 没有理由不在您的现代应用程序构建中考虑它,而要注意我所指出的所有潜在问题。 希望您对浏览器优化的狂野世界有所了解,并可以将这些知识应用于未来的项目。
There are a few articles that get into some detail about hardware acceleration and the will-change
property. I recommend reading up on them as well to firm up your understanding of this umbrella of CSS.
有几篇文章详细介绍了硬件加速和will-change
属性。 我建议也阅读它们,以加深您对CSS的理解。
CSS Will Change Module Level 1 on W3C
CSS将在W3C上更改模块级别1
Everything You Need to Know About the CSS will-change Property by Sara Soueidan
您需要了解的有关CSS的所有内容都会改变属性 ,作者:Sara Soueidan
CSS will-change on MDN
CSS将在MDN上发生变化
High Performance Animations on HTML5 Rocks
HTML5 Rocks上的高性能动画
翻译自: https://www.sitepoint.com/introduction-css-will-change-property/