CSS will-change属性简介

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的技术文档,因此我将在本文中引用很多这些资源,并在最后列出它们。 本文将通过一些快速示例来概述重要部分。

一些背景 (Some Background)

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和硬件加速这两个术语。 让我们快速分解这些术语:

  1. The CPU, or the Central Processing Unit, is the piece of hardware that processes pretty much every computer operation. It’s otherwise known as the motherboard.

    CPU,或中央处理器,是处理几乎所有计算机操作的硬件。 否则称为主板。
  2. The GPU, or the Graphics Processing Unit, is the piece of hardware associated with processing and rendering graphics. The GPU is designed to perform complex graphical computations and offloads some serious process weight from the CPU.

    GPU或图形处理单元是与处理和渲染图形相关联的硬件。 GPU旨在执行复杂的图形计算,并减轻了CPU的处理负担。
  3. Hardware acceleration is a general term for offloading CPU processes onto another dedicated piece of hardware. In the world of CSS transitions, transforms, and animations, it implies that we’re offloading the process onto the GPU, and hence speeding it up. This occurs by pushing the element to a layer of its own, where it can be rendered independently while undergoing its animation.

    硬件加速是将CPU进程卸载到另一个专用硬件上的总称。 在CSS转换,变换和动画的世界中,这意味着我们将流程卸载到了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博客上对此进行了详尽的讨论 ,因此请务必检查一下,但是要注意的关键点是:

  1. We’re interested in using this property to let the browser know ahead of time what changes on an element can be expected.

    我们感兴趣的是使用此属性让浏览器提前知道可以预期的元素变化。

  2. This allows the browser to make the proper optimizations in advance, ultimately leading to quicker and snappier rendering.

    这使浏览器可以预先进行适当的优化,最终导致更快,更生动的渲染。
  3. As mentioned before, the browser needs to know ahead of time what changes will occur. This means that we have to think in advance when to prepare the browser for the change.

    如前所述,浏览器需要提前知道会发生什么变化。 这意味着我们必须提前考虑何时为更改准备浏览器。

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属性,再次释放内存。

浏览器支持 (Browser Support)

The will-change property is fairly new, and is currently supported by the following browsers according to Can I Use:

will-change属性是一个相当新的属性,根据“我可以使用” ,以下浏览器当前支持该属性:

  • Chrome 36 and up

    Chrome 36及更高版本
  • Firefox 36 and up

    Firefox 36及更高版本
  • Opera 24 and up

    Opera 24及以上
  • Android browser 37

    Android浏览器37
  • Chrome for Android 40

    适用于Android的Chrome 40
  • Opera Mobile 24

    Opera Mobile 24

Internet Explorer is the only major missing browser and will-change is listed as under consideration as of this writing.

Internet Explorer是唯一缺少的主要浏览器, 撰写本文时,正在考虑 will-change

最后说明和来源 (Final Notes and Sources)

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的理解。

翻译自: https://www.sitepoint.com/introduction-css-will-change-property/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值