移动端滚动时带动画的列表卡顿,怎么优化才有效?
最近在做移动端商品列表页,每个列表项有个小动画,用transform和opacity过渡效果,但手指滚动列表时特别卡顿,特别是低端机。
我试过把transition属性改成仅transform,或者降低动画持续时间,但效果不明显。代码类似这样:
.list-item {
transition: transform 0.3s, opacity 0.3s;
will-change: transform;
}
.list-item:hover {
transform: scale(1.05);
opacity: 0.8;
}
用Chrome开发者工具模拟低端设备测试,发现滚动时fps经常掉到20以下。有同事说要避免多层复合,但我改了很久都没头绪,求大神指点具体优化方向?
opacity: 0和transform: scale(1)做初始状态,动画只用transform,别用will-change,加backface-visibility: hidden开启硬件加速就行。首先,
will-change这个属性虽然能提升性能,但用得不好也会适得其反。你现在的写法让每个列表项都提前准备好变化,这在商品列表这种长列表里是很耗费资源的。建议只给当前可见区域的元素加上will-change,滚动时动态调整。可以用 Intersection Observer 来检测哪些元素在视口内。其次,你的动画用的是
:hover,这在移动端其实不靠谱,因为触屏设备上的 hover 行为很诡异,可能触发也可能不触发。建议改成点击或其他事件触发。如果一定要保持触摸时的放大效果,可以用 JavaScript 监听 touch 事件,手动控制类名切换。最后,关于卡顿,你可以试试以下代码来优化 CSS:
记得把动画的触发条件从
:hover改成加类名.active,然后通过 JS 控制这个类名的添加和移除。另外,别忘了在实现这些优化的同时,检查一下是否有不必要的第三方库或插件在监听页面滚动事件。有些广告SDK或者统计工具会频繁监听页面行为,导致性能下降。
最后吐槽一句,低端机的坑真是深不见底,尽量把性能压榨到极致吧。