《影子冒险》—— 启动速度优化篇
前言
微信小游戏的制作马上就要进入尾声了,需要着手对小游戏做一些优化,这篇博文将做到的优化项记录分析下来,如果有帮助到大家,可以来体验看看我的小游戏哦,可以扫二维码,或者在微信上搜索《影子冒险》哦。

微信小游戏启动分析

首先上我目前的游戏启动分析图,在CallMain之前,是微信小游戏引擎必须做的工作,在CallMain之后,则是开发者自己的业务逻辑。wasm代码包,首包资源,以及业务启动逻辑,这3大块便是我们需要优化的地方。
首包资源
首先列出我在微信开发者工具中,未优化前的耗时:
包体大小(未压缩):10303KB
下载资源包耗时:3066ms
解压缩资源包耗时:960ms
首包的下载速度和解压效率这块我们无法涉及,我们能优化的点便是尽量减少首包大小,减短下载和解压的时间。的但要减少首包大小,首先我们要知道首包在哪里,以及它里面包含了哪些东西。
当你在Unity当中转换输出微信小游戏后,你可以在webgl目录下找到首包资源:

使用AssetStudio工具,对首包资源进行查看,可以轻松发现,导致包体过大的罪魁祸首,首当其冲便是这个字体,占据了我们大量的空间,其次便是bgm和loading图(这2个是必须的,我希望玩家游戏启动后能听到音乐和能看到loading条):

字体贴图大小优化
目前游戏内使用的TextMeshPro,找到Font Asset资产文件,调低Sampling Point SIze和Padding,这2者调低情况视自己项目情况而定,反正越大生成的图集越大。调低图集尺寸,勾选复合贴图,避免因为图集尺寸不够导致映射不出文字(当然文字很多的情况下,这必然会导致dracall出现问题,但目前我的小游戏文字不多,所以先这么处理,如果后续有性能问题,可以适当调大图集尺寸)。这样优化的第一步就完成了。

第二步我们需要将Source Font File通过动态的方式进行加载,避免Font随font asset文件一起打进首包当中。
首先Font文件要取消勾选IncludeFontData

其次在Font Asset引用中,取消与Font文件的关联,通过代码的方式在游戏启动的时候进行加载:

// 这里我用的AA加载,AssetManager是我自己封装的管理类,兄弟们意会下即可
AssetManager.Instance.LoadAsync("Assets/Abs/Font/AlibabaPuHuiTi-3-105-Heavy.ttf", (obj) =>
{
fontAsset.sourceFontFile = obj as Font;
});
有点要注意,最好将Font文件从Unity中拖出去再拖回来,不然你都不知道哪里还会偷偷引用着这个font文件,导致build的时候,这个font文件还是被打成首包资源。
经过这2步以后,我们可以惊喜的发现,首包资源的大小来到了,6583KB。然后记得,我们在转换成微信小游戏时,打开“压缩首包资源”,最后的得到的效果是:
包体大小(已压缩):2069KB
下载资源包耗时:640ms
解压缩资源包耗时:579ms
当然我这种优化方式目前搜集到资料中是没有人使用到过的,而且有人提到TextMeshPro通过dynamic的方式去运行时去生成会导致内存占用暴涨,这个我还不知道真假,因为时间有限,暂时也不做更多的修改,如果碰到问题,我会再回来继续完善一下。
另外再网上找到了几篇不错的博客,如果觉得我思路有问题的兄弟,可以参考下他们的做法:
- 优化tff资源过大问题:https://zhuanlan.zhihu.com/p/379841120
- 压缩Font Asset贴图纹理:https://zhuanlan.zhihu.com/p/401559453
- 字体与内存分析:https://mp.weixin.qq.com/s?__biz=MzkyOTUxMDM2NA==&mid=2247484415&idx=1&sn=c329dbfb403b88a412cbd940e7638735&chksm=c3bce807456eba1af6554f4aefc620feb4e2c1a197e9f4e23b2bc526a4639d5354a59b11f69f#rd
然后首包资源的优化到此为止,因为时间有限,解决掉这个大头的问题,对我而言目前就够了。
WASM代码包:
首先列出我在微信开发者工具中,未优化前的耗时:
包体大小(已压缩):5586KB
下载时间:812ms
编译时间:2505ms
当你在Unity当中转换输出微信小游戏后,你可以在minigame/wasmcode目录下找到代码包资源:

启动wasm代码分包:

分包后,首包资源删减到2889KB

次包资源达到4867KB:

但说句老实话,最后体验下来并没有什么卵用,就算新增收集个数稳定为0,他还是会在callMain前主动加载子包,并提示:

而且他文档里面有要求收集到的函数要达到总量的30%才行,我努力的把整个游戏玩一遍都达不到这个要求,怀疑是因为我采用了tolua框架实现绝大多数业务场景导致,所以我放弃了。有知道怎么回事的兄弟,可以在评论里讲一下。
业务启动逻辑
各个游戏的业务启动逻辑不尽相同,我这里大致介绍下我游戏目前启动难点的大头问题,在Editor环境下(不用考虑资源下载问题):

| 加载时间 | 包体大小 | |
|---|---|---|
| 加载Font | 496ms | 3712KB |
| 加载同步资源 | 52ms | 5KB |
| 加载Lua资源 | 889ms | 200KB |
| 加载首个场景资源 | 1511ms | 344KB |
但在微信开发者工具环境下则不尽相同:
| 加载时间 | |
|---|---|
| 加载Font | 1428ms |
| 加载同步资源 | 751ms |
| 加载Lua资源 | 6115ms |
| 加载首个场景资源 | 2284ms |
非常吊诡的是,lua竟然加载的比场景还慢。首先怀疑的便是下载出现了大问题,因为lua资源跟其他资源加载方式不一样,是首先加载一个ScriptableObject文件,文件里面存储着所有lua文件的地址,然后将所有lua文件加载进内存当中(另外提一嘴,这里我试了下,所有lua打成一个单独的ab包,和所有lua文件分开打包,后者比前者慢了2倍都不止)。
正好微信小游戏有个预下载的功能,在引擎初始化和首场景准备的过程存在网络空闲的情况,正好这个时机将这4个资源地址添加进行导出:

再重新测试,确实都快了一点,结果如下:
| 加载时间 | |
|---|---|
| 加载Font | 640ms |
| 加载同步资源 | 853ms |
| 加载Lua资源 | 4448ms |
| 加载首个场景资源 | 1697ms |

浙公网安备 33010602011771号