Home >Web Front-end >CSS Tutorial >Learn more about the will-change attribute in css

Learn more about the will-change attribute in css

青灯夜游
青灯夜游forward
2021-06-28 11:14:484607browse

What is the css will-change attribute? How to use it? This article will take you to study the will-change attribute to see when to use it, how to use it, and how to better set will-change in CSS.

Learn more about the will-change attribute in css

will-change

The CSS attribute will-change provides web developers with a way to tell the browser that the element will What methods of change can be used so that the browser can make corresponding optimization preparations in advance before the element attributes actually change. This kind of optimization can prepare part of the complex calculation work in advance, making the page response faster and more sensitive.

IMPORTANT NOTE: will-change is intended to be used as a last resort when trying to deal with existing performance issues. It should not be used to predict performance issues.

Replace translateZ() Hack

For example, when using CSS 3D transform to move an element on the screen, the element and their contents may be lifted to a "layer" where they can be rendered independently of the rest of the page and composited later. This isolates the rendering of content, prevents the rest of the page from having to be re-rendered if the element's transform is the only content that changes between frames, and often provides significant speed advantages.

However, setting an element in a new layer is a relatively expensive operation that can delay the start of the transform animation by a noticeable fraction of a second.

To avoid this delay when using CSS Transforms and other CSS operations, we have long used translateZ (or sometimes translate3d) to lift elements to their own layer, thus enabling hardware accelerated operations to Runs smoother, faster and without glitches. However, this technique - also known as the "translateZ() (or translate3d()) Hack" - comes at a price. Paul Lewis wrote a very helpful post about this, you should definitely check it out if you use this technique. will-change is so we can optimize our animations without having to resort to this hack - or any other hack.

(Learning video sharing: css video tutorial)

Comma separated

You can pass Specify the property names you wish to change (separated by commas) to declare to the browser that you intend to change the scroll position of an element, its content, or the value of one or more of its CSS properties. Most properties will have no effect when specified because user agents do not perform any special optimizations on changes to most properties. However, it is still safe to specify them, although it has no effect at all.

If you expect or plan to change multiple values/aspects of an element, you can provide a comma-separated list of values. The comma-separated list of values ​​can include predefined keywords and/or property names. (See the Examples section below.)

Additional creation of stacking contexts and containing blocks

If you declare any non-initial value for a property A stacking context will be created on the element. Specifying this attribute in will-change will definitely create a stacking context on the element. For example, setting opacity to any value other than 1 creates a stacking context on the element. Therefore, setting will-change: opacity will also create a stacking context, even if opacity is still equal to 1.

Similarly, specifying the attribute in will-change must cause the element to generate a containing block for fixed-position elements if any non-initial value of the attribute would cause the element to generate a containing block for fixed-position elements.

The will-change attribute has no direct effect on the element it specifies, other than the aforementioned creation of stacking contexts and containing blocks - it is just a rendering hint to the user agent, allowing it to be used on certain types of Set up potentially expensive optimizations before changes actually start happening.

Use with caution

That being said, it is important that you know that you should use this property with caution. Different browsers can use information from will-change in different ways, and even a single browser may use it in different ways at different times. Overuse of it may result in the statement being ignored entirely. For example, browsers that promote elements to their own "GPU layer" when the element has will-change . But when there are too many element declarations, the browser will ignore the declarations to avoid running out of GPU memory.

Additionally, will-change should not be used unless the element is known or expected to change in the near future (for example, within a fraction of a second). It should be unset once it is no longer needed:

Set will-change to the property you will actually change on the element that actually changes. and remove them when they stop. - Tab Atkins Jr. (Specs Editor)

Optimization by browsers for upcoming changes is often expensive and, as we mentioned earlier, takes up a lot of machine resources. Normal browser optimization behavior is to remove these optimizations and return to normal behavior as quickly as possible. However, will-change overrides this behavior, keeping the optimization longer than the browser otherwise would.

Therefore, you should always remember to remove the will-change after the element has finished changing so that the browser can resume optimizing any resources declared.

Setting will-change using JavaScript

Setting will-change via JavaScript allows for more fine-grained control, and more browsers ready for changes time, and also allows you to unset it immediately after the animation event ends. Using JavaScript, you declare your changes to the browser and then remove the will-change when the changes are complete by listening for when those changes are complete.

For example, you could listen to when the element (or its ancestor) is hovered and then set will-change on mouseenter. If your element is being animated, you can use the DOM event animationEnd to listen for when the animation ends, and then remove the will-change after animationEnd is fired.

// Rough generic example
// Get the element that is going to be animated on click, for example
var el = document.getElementById('element');

// Set will-change when the element is hovered
el.addEventListener('mouseenter', hintBrowser);
el.addEventListener('animationEnd', removeHint);

function hintBrowser() {
	// The optimizable properties that are going to change
	// in the animation's keyframes block
	this.style.willChange = 'transform, opacity';
}

function removeHint() {
	this.style.willChange = 'auto';
}

Better set will-change in css

If you really want to set will-change in stylesheet for possible To optimize for elements that change on hover, then in order to tell the browser to optimize for the changes you want to occur on hover, you can do the following:

.el:hover {
    will-change: transform;
    transform: rotate()...;
}

This isn't particularly wrong, but it's not Especially useful. You need to declare your intentions to the browser some time before the change actually occurs, rather than when the change occurs, to give it some time to prepare for the change and make the required optimizations. So, in a scenario like this, you could do this:

.el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}

Alternatively, you could set the will-change on hover of the element's container, since it takes some time for the hover event to reach the element itself, and then the browser You can use this time to prepare for changes to the element itself:

.container:hover .el {
    will-change: transform;
}

.el:hover {
    transform: rotate()...;
}

To summarize, remember to use will-change with caution, don't overuse it, only set it when you know the element is about to change, and remember to Cancel the setting after the changes are completed.

Official Grammar

  • Statement:
will-change: auto | <animateable-feature>#

where

<animateable-feature> = scroll-position | contents | <custom-ident>
# The ## tag (#) indicates that you can specify multiple values ​​separated by commas.

    Initial value: auto
  • Applies to: all elements
  • Animation: no

Value ( Values)

auto

This is the default value. It expresses no particular intention. The browser is not notified of any changes and therefore does not perform any optimizations to accommodate any future changes.

scroll-position

Indicates that the author wishes to animate or change the scroll position of the element in the near future. The browser will be properly optimized for this change in advance.

For example, browsers typically only render content in a "scrolling window" on scrollable elements, as well as content that has already passed through the window, thus balancing the time and memory saved by skipping rendering against the need for scrolling. It looks better. Browsers may use this value as a signal to expand the content range around the rendered scroll window so that longer/faster scrolling can be accomplished smoothly.

contents

Indicates something that the author wants to animate or change the content of the element in the near future. The browser will be properly optimized for this change in advance.

For example, browsers often "cache" the rendering of elements over time because most things don't change very often, or just change their position. However, if the element does change its content regularly, generating and maintaining this cache is a waste of time. Browsers may take this value as a signal to cache less aggressively on the element, or avoid caching at all and just continually re-render the element from scratch.

e53daba18c25ef518ad73d82fe4f7af3 (028aa264268b1d80e0a56150adf879cc)

36c67616b8eb707f2ee13847ef0d2ea4 value (see the e53daba18c25ef518ad73d82fe4f7af3 entry for details). Indicates that the author wishes to animate or change a property with the given name on an element in the near future.

For example, browsers often distinguish elements with a non-initial value

transform attribute set from other elements, perhaps rendering them into their own "GPU layer", or using other mechanisms to Easier to make changes quickly. The browser may take the value of transform as a signal that it should promote the element to its own layer immediately before it starts transforming, to avoid any delay involved in re-rendering the old and new layers .

除了通常从 e53daba18c25ef518ad73d82fe4f7af3 中排除的关键字之外,e53daba18c25ef518ad73d82fe4f7af3 值不能是以下关键字之一:will-changenoneallautoscroll-positioncontents

请注意,大多数属性在指定时将不起作用,因为用户代理不会对大多数属性的更改执行任何特殊优化。不过,指定它们仍然是安全的,虽然它根本没有效果。

注:感觉虽然命名为『自定义标志』, 其实主要碰到的还是 css 预定义好的标志,譬如 transform、opacity

例子

下面告诉浏览器期望元素的变换属性发生变化,以便提前进行适当的优化。

.el {
    will-change: transform;
}

上面的 will-change 声明应该通过 JavaScript 添加,然后在更改结束后删除或取消设置 (will-change: auto)。

以下所有的都是可能且有效的 will-change 值:

will-change: contents;
will-change: scroll-position;
will-change: opacity;/* multiple comma-separated values */will-change: contents, transform;
will-change: scroll-position, opacity;

使用小结

想使用好 will-change 并不是太容易,以下使用忠告摘录于官方文档,可见真是太难了。

  • 不要将 will-change 应用到太多元素上: 浏览器已经尽力尝试去优化一切可以优化的东西了。有一些更强力的优化,如果与 will-change 结合在一起的话,有可能会消耗很多机器资源,如果过度使用的话,可能导致页面响应缓慢或者消耗非常多的资源。

  • 有节制地使用: 通常,当元素恢复到初始状态时,浏览器会丢弃掉之前做的优化工作。但是如果直接在样式表中显式声明了 will-change 属性,则表示目标元素可能会经常变化,浏览器会将优化工作保存得比之前更久。所以最佳实践是当元素变化之前和之后通过脚本来切换 will-change 的值。

  • 不要过早应用 will-change 优化: 如果你的页面在性能方面没什么问题,则不要添加 will-change 属性来榨取一丁点的速度。 will-change 的设计初衷是作为最后的优化手段,用来尝试解决现有的性能问题。它不应该被用来预防性能问题。过度使用 will-change 会导致大量的内存占用,并会导致更复杂的渲染过程,因为浏览器会试图准备可能存在的变化过程。这会导致更严重的性能问题。

  • 给它足够的工作时间准备,不要过迟应用: 这个属性是用来让页面开发者告知浏览器哪些属性可能会变化的。然后浏览器可以选择在变化发生前提前去做一些优化工作。所以给浏览器一点时间去真正做这些优化工作是非常重要的。使用时需要尝试去找到一些方法提前一定时间获知元素可能发生的变化,然后为它加上 will-change 属性。

更多编程相关知识,请访问:编程视频!!

The above is the detailed content of Learn more about the will-change attribute in css. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete