opacity与回流重绘

直观上来说,我仍然认为opacity与回流/重排没有半毛钱关系,但chrome控制台的性能分析报告显示确确实实出现了布局相关的渲染流程,但似乎是不确定的,存在某些契机。这太反直觉了,网上的资料也没有特别正确且直观的说明。所以下面只能根据个人推测来理解这个现象

牢记之所以使用 opacity 和 transform 等元素,最终是为了尽可能降低浏览器的计算成本,这一理论是正确的。

结论是,关于opacity的测试分为三种情况,分别是:

  1. 触发回流(Layout)=>重绘(Paint)=>合成(Composite Layers)
  2. 跳过回流和重绘,直接合成处理
  3. 触发重绘=>合成

案例如下

回流案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
.text {
opacity: 1;
}
.opa {
opacity: 0.3;
}
</style>
<script>
window.onload = function () {
setInterval(() => {
document.getElementById('text').classList.toggle('opa');
}, 1000);
}
</script>

<body>
<div>
<div id="app" class="app">
<h1 id="text" class="text">CSS Trigger</h1>
</div>
</div>
<div>

一旦将text类的opacity设置为1,行为将涉及到回流,从而触发重绘和合成。

猜测:将opacity在1和小于1的值之间切换会迫使CSS的layers发生不断的变化(创建新的和渲染层和删除渲染层/创建新的层叠上下文和删除层叠上下文 二者不确定是哪个原因造成的),从而触发layout阶段。

跳过回流和重绘,只进行合成的案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style>
.text {
opacity: 0.99;
}
.app {
opacity: 1;
}
.opa {
opacity: 0.3;
}
</style>
<script>
window.onload = function () {
setInterval(() => {
document.getElementById('text').classList.toggle('opa');
}, 1000);
}
</script>

<body>
<div>
<div id="app" class="app">
<h1 id="text" class="text">CSS Trigger</h1>
</div>
</div>
<div>

猜测1
当text类的opacity被设置为小于1的值时,会形成一个单独的绘制层PaintLayer。从谷歌控制台的性能报告上来看,该流程跳过了回流和重绘,直接进行了合成。推测应该h1标签是满足了提升为合成层的条件,从而跳过了layout 和 paint。

猜测2
浏览器为h1创建了一个单独的渲染层,在两个opacity<1的值相互切换的过程中,都发生在同一个渲染层中,并不涉及层反复新建和删除,从而避免了layout阶段。(但后续为什么不触发paint阶段解释不通,所以觉得猜测1更贴切,下方的案例也贴切猜测1的描述)

跳过回流,只进行重绘和合成的案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<style>
.app {
display: flex;
}
.text{
z-index: 1;
opacity: 1;
}
.opa{
opacity: 0.3;
}
</style>

<script>
window.onload = function () {
setInterval(() => {
document.getElementById('text').classList.toggle('opa');
}, 1000);
}
</script>

<body>
<div>
<div id="app" class="app">
<h1 id="text" class="text">CSS Trigger</h1>
</div>
</div>
<div>

上述写法通过将弹性盒子的子元素z-index设置非auto创建了新的绘制层,但由于不满足提升为合成层的条件,所以仍然需要经过paint阶段,无法跳过。

关于浏览器分层这部分知识并没有找到一个很权威的说法,网上的答案参差不齐,导致我的想法也没办法验证,后续会继续关注这部分知识,在此先记录下当前的想法

作者

徐云飞

发布于

2022-11-01

更新于

2023-02-05

许可协议

评论