本文主要介绍淘宝创意互动开发的一些注意事项以及性能优化方面的最佳实践,旨在帮助服务商同学降低开发成本,少走弯路。
建议使用成熟稳定且适配过手淘小程序的游戏引擎(推荐pixi、egret、laya),游戏引擎需要使用稳定版本;在手淘上未经过业务验证的游戏引擎需要报备,双11等大促场景原则上禁止使用;
1)对于2D游戏,游戏引擎通常同时支持WebGL或者2D方式方式渲染。两种渲染方式都需要进行测试验收,保证出现问题时能通过切换渲染模式降级,最大限度保证业务可用;
2)推荐使用设备分级API,根据机型性能调整业务表现,比如动画在低端机直接展示静图等;
1)推荐始终使用同层渲染Canvas,严禁同层渲染Canvas与WebCanvas混用;
2)gpuAccelerate配置已废弃,请勿再使用;
3)严格控制在屏与离屏Canvas的数量,一个小程序不建议使用多个Canvas,离屏Canvas数量控制在30以内;
4)能用DOM+CSS实现的优先使用DOM方案;互动或者动画场景确认需要使用Canvas的,也请控制渲染区域的大小;
5)推荐使用WebGL1.0而不是2.0;
6)推荐使用canvas#requestAnimationFrame而不是setTimeout实现renderLoop;
7)WebGLContext#readPixels接口行为与浏览器实现不一致,由于历史原因,目前双端的实现中,readPixels之后会进行一次flipY操作,开发者可以通过 canvas.getContext('webgl',{enable_flip_y_after_read_pixels: false})扩展选项控制具体行为;
1)Android机型复杂,测试需要覆盖小米/OV/华为等主流机型,做好兼容性测试,同时关注中低端机型的稳定性;
2)除业务功能验证外,也请充分测试各类边界场景,如反复退出重进、熄屏、退到后台再返回、跳转到另一小程序再返回等等;
1)淘宝Canvas技术支持统一由@楚奕 负责,提问请结构化描述问题现象、复现路径、出现版本、设备信息等;
2)ISV技术同学需加入淘宝互动内测群,手淘版本迭代、重要行为变更等均会在群内通知,务必关注并响应;
下面分享关于性能优化的一些最佳实践。在此之前,请先阅读小程序通用性能优化解决方案。
优化项目 |
详情说明 |
内存标准 |
单小游戏内存增量不超过300MB,单小部件不超过80MB。 |
开发阶段内容调优 |
目前平台仍未提供有效内存诊断工具,现阶段建议开发者先在Web平台借助Chrome Devtools或者游戏引擎配套IDE上进行内存调优,调优完毕后再进行导出。 |
图片优化 |
图片是内存占用大户,70%以上的性能审核不通过的原因都是因为图片内存超标,有如下常规优化手段。 ① 确认是否一定需要图片。对于矢量图形或者简单的纯色、渐变等图形可以使用Canvas渲染,特别是Shader,功能很强大,思路可借鉴Taobao FED文章《活用Shader,让你的页面更小,更炫,更快》; ② 使用合适的图片格式。PNG与JPEG是常用的图片格式,PNG是无损压缩,且支持Alpha透明度,但是体积较JPEG更大,因此需要分场景选择合适的图片格式,在图片质量与内存之间需要进行权衡; ③ 图片压缩。使用tinypng等工具压缩图片文件大小; ④ 尺寸优化。在满足视觉要求的情况下,尽可能地缩小图片尺寸,比如将一张 256*256 图片缩小成 128*128 尺寸,就减少了 75%的内存占用; ⑤ 压缩纹理。使用纹理压缩工具将图片转成压缩纹理格式(使用时需要注意判断设备支持哪种格式的压缩纹理),不过使用压缩纹理后,体积会变大,会影响加载时间,需要注意权衡; — Egret压缩纹理; — Laya压缩纹理; ⑥ 裁剪图片透明区域。对于存在大量透明区域的素材,需要通过工具裁剪掉透明区域; ⑦ 资源复用。对尺寸比较大的资源,尽量进行复用,如界面背景等等; ⑧ 九宫格拉伸(点9图)。当界面资源要显示的图片尺寸比较大,且中间部分是由连续有规则的像素组成时,通常使用九宫格拉伸的办法,大幅度减小图片尺寸的大小。 ⑨ 根据屏幕分辨率请求不同尺寸图片。 |
帧动画优化 |
① 首先确认是否一定要使用帧动画,在可能的情况下。使用Lottie或者骨骼动画替换帧动画; ② 抽帧。降低动画帧数,这是最有效的优化手段; ③ 图片优化。使用如上图片优化手段优化单帧图片; |
资源优化 |
① 不用的资源及时释放; ② 使用WebGL或者游戏引擎务必注意显存释放问题。显存不像内存,内存有垃圾回收机制,而显存需要手动释放,因此需要利用相关API在合适的时机显式释放,参考: — Laya批量销毁释放内存; — Egret销毁资源; |
游戏场景优化 |
① Canvas画布大小按需设置,不要设置的过大; ② 减少屏幕中渲染的对象,比如有的游戏对象可以合并显示,不可见的对象及早销毁,只渲染可见区域的对象等等。另外,游戏中有的页面可能只是简单的静态内容呈现,没有复杂的动画交互,这类页面可以用DOM来实现。 ③ 对于粒子动画,尽量减少粒子的数量; |
优化项目 |
详情说明 |
减少drawCall |
/ |
减少重绘 |
对于Egret引擎,按需使用cacheAsBitmap,减少重绘。 |
减少每一帧的计算量 |
有的计算并不需要在每一帧都处理,这时可以每隔几帧或者间隔一定时间才做一次计算,比如检测某些对象是否不可见了,我们允许适当的延迟,没必要每一帧都去检测。 |
按需渲染 |
游戏引擎一般都是调用requestAnimationFrame或者setTimeout不停的循环执行的,这是游戏做动画交互的基础。但实际上,有些游戏并不是一直都有动画的,比如某些时刻整个页面都是静止的,如果继续做循环渲染就会导致没必要的性能消耗,这时候我们就可以停止掉游戏引擎的循环逻辑或者降低帧率。 |
控制渲染区域 |
开启脏矩形检测如果引擎支持的话。 |
少用filter或者mask遮罩特性 |
/ |
按需开展抗锯齿 |
/ |
优化项目 |
详情说明 |
控制图片大小 |
图片资源是小程序加载资源项中应用范围最广、影响最大的一部分,除去对启动过程中包资源大小的影响,还体现在 API 网络请求中对图片资源的加载。 优化建议: ① 避免使用大图,压缩图片大小。 ② 根据显示区域大小合理控制图片大小。 ③ 格式转化,可将图片格式转化成 jpeg/webp。 ④ 图片开启 HTTP 缓存控制,下次加载同样图片,直接从缓存读取。 |
降低首屏渲染所需资源 |
首屏资源尽量置于包内,避免请求CDN,这对于弱网用户会导致较长的加载时间。 |
合理使用分包加载 |
对体积较大的小程序项目,或JS执行时间过长,建议使用此功能。主包只保留最常用的核心页面(首页、tabBar 页面和其他公共资源),将小程序中不经常使用的页面放到多个分包中,启动时只加载主包,使用时按需下载分包,不要一次性下载整个代码包,以提升首页启动速度。 |
尽快渲染 |
缩短业务代码注入完成到首屏渲染指令的时间。比如: ① 减少初始代码大小,降低代码注入时间; ② 简化首屏逻辑,比如不依赖第三方引擎进行轻量渲染。 |
兜底图 |
如果资源加载时间过长,请设置兜底图或者loading动画以减少跳失率。 |
合图 |
使用雪碧图减少IO次数,提升加载速度。 |
需要安装依赖@tbmp/mp-cloud-sdk 使用命令npm install @tbmp/mp-cloud-sdk。更多云应用内容请访问【云应用】文档。
需要安装依赖@tbmp/mp-cloud-sdk 使用命令npm install @tbmp/mp-cloud-sdk。