一、帧动画方案:
帧动画适合于一些特别复杂的动画场景(比如小动物跑步),前端用css或者js难以实现其效果,用gif或者apng又不好控制,这时候就会让设计师提供一系列图片,逐帧播放来达到动画的效果
这种方案有点是需要的开发量很低,并且效果也最接近于设计稿,但是缺点是性能比较差,这里分为两种情况:
1.多张图片,每张1帧
这种方式比较适合于在canvas上绘制帧动画,可以先将所有的图片预下载下来,存放到image数组里,在需要绘制时drawImage传入image,可以避免在播放时才下载图片导致的闪烁问题
这种方式的性能问题是会导致请求量很多,如果你没有使用http2.0或者quic等技术,很可能会遇到浏览器的并发请求数量限制
比如帧动画一共50张,浏览器的并发限制是10,那么下载时间近似于50/10=5倍的图片下载时间,并且这个过程中会阻塞其他同域名的网络请求,会直接对页面加载时间的产生很大影响
2.单张图片上合并所有帧
这种类似于雪碧图的方案,适合于用css绘制动画,用background-position来控制当前展示哪张图片(经过实验发现,在小程序dom上,上一个方法并不适用,因为频繁切换background-image会导致闪烁)。这种方式也同样需要预加载,可以直接使用浏览器缓存,提前加载一次雪碧图。
这种方式的性能问题是会导致单张图片k数和尺寸过大,单张图下载时间会很长,并且大尺寸图片在小程序中会更加占内存
二、性能优化方案
上面两种方案都有性能问题,那么有没有性能优化方案呢,下面列举几个我们常用的:
1.抽帧,一般而言帧动画多少都是可以抽些帧的,比如50张图的帧动画,抽掉一半的帧(比如偶数帧),只留25张图片,在视觉上不会有太大影响,性能消耗能减少50%,甚至可以抽2/3的帧,视觉上会有损失,适合用户不会太关注的动画
如果做的复杂点,可以延时补帧,在性能有充裕时,将未加载的图片下载并补充到播放数组中去
2.首帧渲染,在性能很差的情况下的降级方案,先用第一帧的静态图顶着,之后性能有充裕时再去补充剩下的部分
3.多帧合并,这种方案只能用于canvas绘制,他是将几张图合并成一直稍大的图来渲染,是一个平衡方案,可以平衡图片数量多和图片尺寸太大占内存多的问题,比如我们一般将4张帧动画合成一张渲染,可以减小75%的图片下载数量,并且每张图片也不会尺寸很夸张
这种方案也可以结合使用抽帧、首帧渲染的优化方案,比如将1357合成一张,等性能有充裕时在去补充2468合成的图,可以理解为将帧动画的一位数组转化为了二维数组
三、优化方案的动态选择
合理的优化方案选择应该是动态的,是根据当前用户的真实情况来调整的,比如当前网速很差和网速很好的优化方案不应该是一样的,甚至对于性能良好的情况,可以不使用上述的任何优化方案,以下是我们常用的几个观察项:
1.网络速度,简单处理可以用当前的网络是wifi、4g还是3g、2g来判断,更准确的方式是抽一部分资源来做网速测试,比如选择10张图片,实时测量他们的加载速度,来决定后续加载哪些图片
2.内存,在小程序端可以监听onMemoryWarning,来检测目前的内存使用情况,要注意这个事件触发已经说明小程序马上要因内存不足而杀掉了(下图是官方给的说明),需要立刻做降低内存的动作,比如关停帧动画,释放多余图片(图1)
3.帧率,可以用requestAnimationFrame的触发时间间隔来检测帧率,一般在游戏中比较常用,帧率低说明用户已经遇到了卡顿或者掉帧的情况,需要暂停帧动画来降低cpu占用
四、帧动画内存占用对比
以下数据为在华为P9实测,单位:mb
(见图二)
可以看到,小游戏平均比小程序少占用200mb左右内存,可以认为是框架本身的优势
帧动画张数越多,图片尺寸越大、k数越大,占用内存越多
五、工具推荐
最近刚好发现了一个雪碧图合成软件:TexturePacker 4.x
选这个多文件打包,就可以方便的将散图合成多张雪碧图(见图三)
实测这种分文件打包的方式比起单张大图,能很大程度上的减少内存占用
声明:本文内容由脉脉用户自发贡献,部分内容可能整编自互联网,版权归原作者所有,脉脉不拥有其著作权,亦不承担相应法律责任。如果您发现有涉嫌抄袭的内容,请发邮件至maimai@taou.com,一经查实,将立刻删除涉嫌侵权内容。