某站 banner 在 Firefox 上的渲染
TL; DR
在禁用自动硬件加速情况下, Firefox
在渲染这个 banner
的时候似乎没有使用 GPU
加速,使用<iframe>
可以缓解这个问题。
Detail
测试环境:
- 显卡: i7-6700HQ 核显
- Firefox: 81.0.1 禁用自动硬件加速 (我笔记本的硬件加速有些驱动相关的问题)
- Chrome: 86.0.4240.75
为了方便分析首先实现一个 banner,先把模板 HTML 部分写好,之后用 React 来实现动画效果。
最开始想去某网站前端看一下他们的一些动画效果参数,在 DOM
改变处下了断点,然而断下来的地方是混淆的 JS 代码。丢到 jsnice 解了混淆后勉强能看,然而转念一想此处 CSS
属性变化(主要指transform
)应该只是一个线性变化,测一个极限值自己算要方便的多,实际测试中发现filter: blur
有些不是线性变化的,取了几个点做了个拟合(别拟合了,还是点对点直线好用),效果差强人意。
框架弄完了来看一下当前的性能数据,在 Firefox 上开了个性能分析看到动画只有 8fps,和某网站首页动画的帧数 (7fps) 基本相同。这当中每次重绘的耗时都在 80-100ms。一次重绘如果需要 0.1s 的话,就算 DOM 属性计算这些步骤不耗时,浏览器一秒内最多也就能渲染 10 帧。
然后为了比较一些性能数据,我开了个 Chrome,我发现这个动画在 Chrome 上可以跑到 50 fps!
最开始我以为是合成层的处理方式不同导致的渲染效率不同,后来查了些资料,开了调试设置对比了一下,似乎并没有不同之处。之后我找到了一篇关于
CSS 性能优化的资料,里面提到有一些元素和 CSS 会触发 GPU
渲染。对照了一下某网站的实现,怀疑其中translate: rotate(0deg)
这一项就是用来触发
GPU 加速的,虽然不知道为什么在 Firefox
上没有生效。在一些尝试后,我发现position: fixed;
和<iframe>
可以在
Firefox
上触发加速,就像上面你看到的那样。这样大概能达到 26fps
,和最开始的 8fps 相比好了很多了。
虽然和 Chrome 相比还有差距,但是我最近没什么空深究这个问题,准备暂时就这样搁置了。
Refer
CSS 硬件加速的好与坏: 一些有用的测试方法