Kyr1os' Blog

May the wind guide your road

0%

某站20秋banner在Firefox上的渲染


某网站🍁秋季的banner设计的挺好看的,然而在Firefox上的实际动画渲染效果却一言难尽,所以自己尝试摸索了一下。

TL; DR

相较于Chrome, Firefox在渲染这个banner的时候似乎没有使用GPU加速,使用<iframe>可以缓解这个问题。

Detail

测试环境:

  • 显卡: CPU自带集成显卡
  • 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上可以跑到50fps!

最开始我以为是合成层的处理方式不同导致的渲染效率不同,后来查了些资料,开了调试设置对比了一下,似乎并没有不同之处。之后我找到了一篇关于CSS性能优化的资料,里面提到有一些元素和CSS会触发GPU渲染。对照了一下某网站的实现,怀疑其中translate: rotate(0deg)这一项就是用来触发GPU加速的,虽然不知道为什么在Firefox上没有生效。在一些尝试后,我发现position: fixed;<iframe>可以在Firefox上触发加速,就像上面你看到的那样。这样大概能达到26fps,和最开始的8fps相比好了很多了。

虽然和Chrome相比还有一半的差距,但是我最近没什么空深究这个问题,准备暂时就这样搁置了。

Refer

CSS硬件加速的好与坏: 一些有用的测试方法

CSS performance optimization