React 前端导航

正确使用 CSS 的 will-change 属性

will-change 是什么

css will-change是一种优化技术,它用于告诉浏览器哪些属性将会在未来的某个时间发生改变。这样,浏览器就可以事先分配和优化相应的资源,预先优化处理这些属性,从而提高网页渲染性能。

will-change的使用方法

要使用will-change,只需将它应用于你要进行性能优化的元素上。

.element {
  will-change: transform;
}

在上述示例中,我们告诉浏览器,该元素即将发生变换(transform),以便浏览器在渲染时提前分配所需的资源。

注意:过度使用will-change属性会产生反作用,浪费内存和CPU资源,因此不要将will-change应用于太多的元素和属性上,只应用于需要进行大量动画和变形处理的元素上。

will-change的原理

一句话来说就是当will-change属性被应用到一个元素上时,浏览器将会在内部为该元素创建一个图层,并将该元素绘制到该图层中。这个图层与普通的图层不同,它被称为“合成图层(Composited Layer)”。浏览器可以利用这些合成图层将处理、渲染和复合操作分层,使GPU更有效地处理页面元素,从而提高网页性能。

1. 渲染流程简介

浏览器在渲染网页时,会经历一系列的步骤,如样式计算、布局、绘制和合成。为了提高性能,浏览器会尽量避免进行不必要的计算和操作。

2. will-change的作用

will-change的作用就是告诉浏览器某个元素将要发生的变化,从而使浏览器在渲染过程中提前分配和优化相应的资源。

例如,当我们设置了will-change: transform时,浏览器会为该元素创建一个独立的图层,将这个图层标记为“即将变换”。这样,在进行布局和绘制时,浏览器就可以更高效地处理这个元素,而无需重新计算整个渲染树。

加入will-change后,元素会被提升到单独的复合层,动画(重绘、重排)的操作只会在单独复合层上进行,减少了原来的页面层重绘和重排的行为 注:每一个元素单独加入will-change都会单独创建一个复合层,如果给大量的元素加上will-change就会创建大量的复合层,反而会影响性能

3. will-change的优化效果

使用will-change可以带来以下优化效果:

  • 减少渲染阻塞:浏览器可以提前分配和优化资源,减少渲染阻塞时间,提高页面的响应速度。
  • 减少重绘和重排:浏览器可以更好地管理渲染过程,避免不必要的重绘和重排,从而提高渲染性能。
  • 硬件加速:某些浏览器对will-change属性会进行硬件加速,进一步提升性能。

4. will-change使用的时机

在很多关于will-change的描述,都能够看到类似下面的一段话

在实际更改的元素上将 will-change 设置为您将实际更改的属性。并在他们停止时将其删除。- Tab Atkins Jr.(规范编辑者)
至于为什么?大部分的描述都是因为will-change会消耗浏览器GPU资源
当元素有 will-change 时,将元素提升到它们自己的“GPU 层”的浏览器。但有太多元素声明时,浏览器将忽略声明,以避免耗尽 GPU 内存

所以对于will-change的使用应该控制时机

const targetNode = document.getElement("#targetId");
const setWillChange = () => {
  targetNode.style.willChange = "transform,opcity"
}
constt removeWillCHange = () => {
  targetNode.style.willChange = "auto"
}

在适当的时机移除will-change就是减少浏览器的复合层,避免过度使用will-change带来性能问题

四、iphone上使用will-change会导致图片模糊、文字模糊问题

在iphone上可以看到如果给元素加上will-change,可能出现模糊现象,分析一下问题

  • 加入will-change,元素会提升到复合层,提升到复合层后,浏览器做了什么事?
  • 安卓不会而iphone会,iphone上使用的是safari浏览器

解:

  1. will-change加入后,元素提升到复合层,浏览器其实会进行 光栅化

  2. 至于为什么safari浏览器在元素提升到复合层后,进行光栅化会导致模糊问题,在我们翻阅了各家浏览器内核论坛后,找到一些资料:https://groups.google.com/a/chromium.org/g/blink-dev/c/Ufwrhx_iZ7U

    大概的内容就是:

    在2016年之前,不止safari,谷歌浏览器也是存在模糊的问题,原因是提升复合层后,光栅化的时候,设备比例的变化,导致绘制 图像 的过程变模糊,谷歌是在2016年解决的这个问题,所以现在看来我们会在iphone上发现模糊问题,在安卓机上并不会。

    iphone上模糊的问题,可以通过在执行完重排重绘后在适当的时机移除will-change(让元素回到原来的页面层,不在单独一个复合层)就可以解决。

五、什么操作会将元素提升到复合层

在CSS中,以下属性可以将元素提升到复合层:

  1. will-change 属性:通过使用 will-change 属性,告诉浏览器该元素即将发生某种变化,浏览器可以提前将其提升到复合层以进行优化。
  2. transform 属性:当使用 3D 或 2D 变换时,浏览器会自动将 transform 属性应用的元素提升到复合层。常见的变换函数如 translate(), rotate(), scale() 等。
  3. backface-visibility 属性:当使用 backface-visibility: hidden 来隐藏元素的背面时,浏览器会将该元素提升到复合层。

需要注意的是,将元素提升到复合层也会增加内存的占用和渲染的复杂性,因此不应滥用。只有当元素需要频繁改变或有复杂的动画效果时,才建议将其提升到复合层。

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/130

#css#will-change

相关推荐

css text-align:justify为什么不生效

实现文本两端对齐,css text-align:justify不生效解决办法

Chrome 发布新的 CSS 视口单位:svh、lvh、dvh!

介绍 Chrome 新发布的视口单位:svh、lvh、dvh