触及Webview陷阱,伪元素动画带来的崩溃
2023-10-08 22:27:15
发生了一次伪元素动画引起的webview崩溃
引言
这篇文章将分享一个真实的技术案例:在移动端H5项目中,滥用伪元素动画导致了页面崩溃。如果您正在进行移动端开发,那么这篇文章值得一读。在遇到类似问题时,可以通过检查是否有不必要的伪元素动画来排除故障。
背景
前不久做了一个imo年终盛典的h5移动端活动项目,活动主页有三个排行榜页面,以及任选其一随机选取查看更多。
四个页面均有一个通用样式,是一个旋转圆圈进度条,和排行榜信息叠加展示。
问题复现
项目测试的时候都是正常的,但是众所周知,h5项目总是会存在千奇百怪的兼容问题,永远可以找到你想不到的坑。
问题复现时,页面只有旋转圆圈进度条在转动,排行榜信息一直加载不出来。通过远程真机调试查看了下,请求都正常发送了,接口也都返回了正确的数据。那就只能是返回的数据在页面展示时出了问题。
伪元素动画的罪魁祸首
通过逐一排查最终定位到了伪元素动画是罪魁祸首。去掉伪元素动画,排行榜信息就能正常加载并展示。
伪元素动画的样式如下:
.progress-bar .mask {
animation: progress-bar-mask-rotate 1.2s infinite linear;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
height: 124px;
width: 124px;
}
@keyframes progress-bar-mask-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
伪元素animation设置了一个旋转动画,这是很常见的动画,在很多场景下都会用到。但是由于历史原因,早期为了更好的兼容性,移动端的很多浏览器都是通过离屏渲染来实现动画的,而离屏渲染的实现本质上就是创建了一个新的图层,层级叠加到页面上。由于webview层级叠加后可能会出现问题,所以现在很多移动端的浏览器(主要是安卓系)都移除了离屏渲染的功能。
但是问题来了,如果开发者在页面上使用了伪元素动画,并且动画的样式是通过transform属性来控制的,那么这些浏览器就会进行层级叠加,也就是创建新的图层。而新的图层会消耗大量的内存,当图层数量过多时,就会导致webview崩溃。
解决方案
在移动端h5开发中,应该避免使用伪元素动画,或者尽量减少伪元素动画的使用。
对于已经使用伪元素动画的页面,可以通过以下方式来解决问题:
- 减少伪元素动画的数量。
- 使用transform-style: flat来消除层级叠加。
- 使用GPU加速来提升动画性能。
总结
伪元素动画是一个非常有用的工具,可以用来创建各种各样的动画效果。但是,在移动端h5开发中,应该谨慎使用伪元素动画,因为滥用伪元素动画可能会导致webview崩溃。
如果您正在进行移动端h5开发,那么希望这篇文章能够帮助您避免出现类似的问题。