移动端CSS动画导致FPS不达标怎么办?
我给页面加了个轮播图动画,用transform和opacity组合过渡效果,但在低性能手机上直接卡成PPT,fps监测工具显示掉到20多帧。尝试把transform抽出来单独写还是没改善:
.slide-item {
transition: opacity 0.5s ease, transform 0.5s ease;
}
@keyframes slideFade {
0% { opacity: 1; transform: translateX(0); }
50% { opacity: 0.5; transform: translateX(20px); }
100% { opacity: 0; transform: translateX(100%); }
}
已经试过设置will-change: transform opacity,也把动画抽到webworker里,但帧率还是不稳定。是不是同时动画这两个属性有问题?有没有更轻量的实现方式?
我之前用过一个轻量方案:把动画拆成两层,单独用position: absolute把要动的元素拎出来,这样能减少重绘范围。关键代码如下:
另外可以考虑改用js控制动画,用requestAnimationFrame来驱动帧率,比纯css更可控。插件可以选gsap或者anime.js,这两个库对移动端优化得不错。
如果不想引入库,自己写的话可以试试只用translateX,opacity变化容易引起重绘。把opacity 0换成visibility:hidden,或者直接用透明度+透明通道变化,帧率会稳定些。比如:
这样虽然动画效果会简单点,但胜在稳定。低端机上动画不要太花哨,能省一帧是一帧。
可以试试这样:
1. 只用transform来做动画,把opacity去掉。因为transform是GPU加速的,性能更好。
2. 把translateX(100%)改成具体数值,比如屏幕宽度是375px就写translateX(375px),这样浏览器更容易优化。
3. 给父容器加
backface-visibility: hidden;和perspective: 1000;,强制开启GPU加速。新的代码大概这样:
另外,web worker对CSS动画没帮助,因为它只处理JS线程。如果还是不行,建议用GSAP这种专门的动画库,它对性能优化得很好。
最后提醒一下,轮播图其实可以用原生的swiper之类的现成组件,人家都帮我们优化好了,能省不少事。