CSS的will-change,为什么有时候能优化几十倍的性能?

原文来源于:稀土掘金;作者:超神熊猫

如有侵权,联系删除

前言

大家好,我是考拉🐨,分享一篇好文~

前言

will-change 一个既陌生又熟悉的属性,以前在使用这个属性的时候,单纯是因为要做性能优化,加上will-change会使得动画变得流畅一些,但是实际上到底是什么原因导致加上will-change就能使得动画流畅,它有什么弊端?
一个老同事,前几天跟我说他挨了领导的骂,说他滥用will-change这个属性,知其然不知其所以然。
我有点茫然,使用will-change应该是好事,能够提升性能
但是当他给我介绍他的用法的时候,我想说的是,“骂你的队伍能加我一个不咯?”

html
复制代码
<template>
  <div class="list">
    <div class="item" v-for="i,k in lists" :key="k">
      ...
    </div>
  </div>
</template>

<style>
.item {
  will-change: transform;
}
</style>

给一个循环的元素加入了will-cahnge,这意味着网页上会有大量的元素加入了will-change,并且长留存

在现代网页设计中,性能优化成为了一个重要的议题。一种关键的优化工具是CSS属性will-change,它可以告诉浏览器元素将要发生的变化,从而提前分配资源并优化渲染。本文将深入探讨will-change的使用和原理,以帮助开发者充分发挥其潜力,提升网页性能。

一、什么是will-change

will-change是一个CSS属性,它可以告诉浏览器某个元素将要发生的变化。通过明确指定这些变化,浏览器可以事先分配和优化相应的资源,从而提升渲染的性能。

二、will-change的使用方法

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

css
复制代码
.element {
  will-change: transform;
}

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

值得注意的是,因为will-change是为了性能优化而设计的,滥用它可能会带来负面影响。只在需要优化的元素上使用will-change,避免对所有元素都进行指定。

三、will-change的原理

要理解will-change的原理,我们需要了解浏览器渲染流程的基本概念。

1. 渲染流程简介

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

2. will-change的作用

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

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

加入will-change后,通过观察复合层,如图下

图片

layer-start.gif

加入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的使用应该控制时机

图片

ray-so-export (1) (1).png

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

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

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

  • 加入will-change,元素会提升到复合层,提升到复合层后,浏览器做了什么事?

  • 安卓不会而iphone会,iphone上使用的是safari浏览器

解:

  1. will-change加入后,元素提升到复合层,浏览器其实会进行 光栅化
    关于光栅化的内容可以查看这篇文章 zhuanlan.zhihu.com/p/450540827[1]

  2. 至于为什么safari浏览器在元素提升到复合层后,进行光栅化会导致模糊问题,在我们翻阅了各家浏览器内核论坛后,找到一些资料 groups.google.com/a/chromium.…[2] (需要科学上网,才能查看)

图片

大概的内容就是:
在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 来隐藏元素的背面时,浏览器会将该元素提升到复合层。

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

六、结论

will-change是一种强大的性能优化工具,在现代网页设计中发挥着重要作用。通过明确指定元素将要发生的变化,浏览器可以提前分配和优化相应的 .

使用上也有需要注意的点:
1. 不要给大量的元素添加will-change,这会导致创建大量的复合层

2. 注意使用的时机,在需要进行重绘/重排行为的时候,才考虑加上will-change,使用完后需要再适当的时机移除,释放浏览器资源

3. 是否真的需要will-change,如果页面在性能方面没什么问题,没有必要放个will-change来换取那微乎其微的收益,如果收益客观,可加,如果加与不加,差别不大,没必要 

CSS的will-change属性是一种优化技术,用于提示浏览器即将发生的变形,以提高性能。这个属性可以告诉浏览器,某个元素将要发生变形,让浏览器做好相应的优化准备。 要使用will-change属性,只需在元素的样式中添加一行CSS代码:will-change: transform; 这样就可以提示浏览器该元素将要进行的变形,比如旋转、缩放等等。这样一来,浏览器可以在元素发生变形之前做一些性能优化的准备工作。 为了使元素在达到active状态时能够进行变形,我们可以使用以下CSS代码: .will-change { transition: transform 0.3s; } .will-change:hover { will-change: transform; } .will-change:active { transform: scale(1.5); } 首先,我们为元素添加了一个过渡效果,当transform属性发生变化时,过渡时间为0.3秒。然后,在元素悬停时,我们使用will-change属性告诉浏览器该元素将要进行的变形,以进一步优化性能。最后,我们使用:active伪类来定义元素在active状态下的变形效果,这里我们将元素的缩放比例设置为1.5。 通过使用will-change属性,我们可以提前告知浏览器某个元素将要发生的变形,以便浏览器做出相应的优化准备,从而提高页面的性能和用户体验。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [CSS will-change属性简介](https://blog.csdn.net/culi3182/article/details/108341766)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [CSS will-change 属性](https://blog.csdn.net/sunsineq/article/details/107110451)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值