1.概述
OK 今天跟大家聊一下这个首包优化,很多人做优化,都是东改一下、西调一下,没有目标,看似优化了一堆,实际没有优化对地方,又或者是从网上查一下,然后根据网上给出的优化方法进行一些优化,但是根本的问题还是没解决。今天咱们就一起解决这个性能问题。(本文以微信小游戏为例,其实无论是小游戏包还是android包又或者其他包体,原理都是一样的)。
2.为什么要优化首包?
- 做优化之前,咱们要知道为什么要优化首包?这个就比较好理解了,微信|抖音 小游戏相比于传统移动端游戏,能让咱们点击即玩,更快的进游戏以为着更高的转化率,这对买量很有帮助。
- 在看包里有什么前,咱们可以先看微信小游戏的启动流程图,这个是官方文档里面的启动流程图
- 从这个启动流程来看,他分为三部分,咱们进行包体优化,主要是针对第一步,我们也可以看到官方给我们的建议是代码量精简,CodeSize控制在4M以内,首包资源包简化,DataSize控制在5m以内。从这个流程来看,我们优化代码包资源包能减少下载时间,以及编译的时间,从而减少游戏的启动时间。
3.怎么优化首包代码?
想要缩小微信小游戏代码包,首先我们得搞懂一件事:wasm.br 这个代码包里面到底装了什么?
整个代码包由三大部分构成:第一块是我们自己写的业务逻辑代码;第二块是庞大的 Unity 引擎底层代码;第三部分是 Spine、网络库这类第三方插件库。最终打包输出,大家拿到的就是压缩后的 wasm.br 文件。
很多人有个疑问:我只能看到最终的 wasm 文件,我怎么知道里面包含了哪些 C# 代码?具体的哪些库被打进来包里了?咱们光看这个最终的wasm文件是看不出来的,所以我们只能往前找,看看是哪些文件打进包里了,想搞明白这点,我们就要完整梳理 Unity WebGL 的打包编译链路。
我们从头走一遍流程:
第一步,我们写的 C# 代码,先编译成 IL 中间语言;
第二步,引擎执行代码裁剪(Stripping),根据使用情况剔除没有调用的代码,得到剪裁后的 IL 文件(一堆dll文件);
✅重点来了:代码包瘦身最关键的观测节点,就在这一步! 我们可以导出、对比裁剪后的 IL,一眼就能看出哪些多余类、接口没有被裁掉,提前优化,而不是等到最后编译完 wasm 再返工。
第三步,IL2CPP 工具把裁剪完成的 IL,转译成标准 C++ 源码(一堆Cpp文件);
第四步,再交给 Emscripten 编译器,把 C++ 编译成 WebAssembly,也就是最终的 wasm 文件,最后压缩成 wasm.br。
简单梳理整条链路:
C# 源码 → IL → 【裁剪 IL(优化观测关键点)】 → C++ 中间代码 → Emscripten 编译 → wasm → wasm.br
所以大家记住:不要盯着最终 wasm 去猜代码冗余。去猜哪一个插件有没有用到过,那样太笨重了,往往只是删除了一些无关紧要的代码,一定要利用好 IL 裁剪阶段的中间产物dll文件,根据这些dll,来决定去优化哪一个,去删减哪一个。现在我们已经将优化wasm转换为了优化 dll文件,同时这些dll 也给了我们指引,告诉了我们他们叫什么?我们能根据这些名字进行优化即可。
举个例子,大家肯定是把优化重心放到这些大的dll进行优化,优化的方法无外乎 删除和删减, 删除无用的库以及对一些重度的库进行删减
(1)unity VisualScripting.Core 这个是unity可视化脚本的核心代码库,如果我们没有用到是不是可以把这个删掉?
(2)也可以看到Newtonsoft.Json.dll 和 LitJson.dll 两个json序列化的库 那么我们是不是可以删一个?
(3)对于一些比较大的库 也就是Assembly-CSharp.dll 或者mscorlib.dll ,我们怎么对他进行删减呢,我们可以使用dnSpy反编译来查看 这个库里到底用到哪些方法函数,来帮助我们进行删减?
这就是主要优化方法,同时还有很多官方给出的优化方法,也同样很有效,需要大家同时进行优化:
- 打包方式从更快 改成压缩的更强
- 开启代码剪裁(官方推荐 等级改为最高)
- 开启br压缩
- 开启代码分包
4. 怎么优化首包资源
上面我们通过中间产物dll来确认首包代码包里面有什么,那么首包资源包怎么进行问题转化呢?
咱们可以思考一下,同一个项目,同样的资源,可以打出android包,可以打出微信小游戏包,在这个项目中场景资源、Prefab 、音效、动画,等等这些文件,资源依赖关系完全一致,那么我们就可以将我们现在的问题 是不是就可以转变为分析如果降低Android包的资源大小。
那么咱们为什么要将问题,转换为android包呢,因为咱们有AssetStudio 这个好用的工具,他能查看android包里面的资源到底有什么?用这个工具打开解压后android包目录下的 assets\bin\Data 目录,可以看到里面的有的各种各样的资源,可以根据这些内容来定位首包资源包有什么!
举个例子:
- 我们可以看一下 这些资源,哪些资源是首包用不到的,可以拆分出来首包资源与后续资源
- 同时我们可以看到很多资源其实来自Resources目录,可以清理 Resources 目录中的无用资源
- 项目中的字体非常大, 可以单独拆分出来一个首包字体
这样我们的问题就具象化,将优化首包资源,转换为优化某个或某些具体的资源,我们可以针对这些需要优化的资源,制定专门的优化策略。
5. 更方便的首包查看工具
问题来了,有些项目无法打出来android包怎么办?以及上述介绍的两种方式都不太能方便的查看首包内容,那么有什么方式能简化这个流程呢,下面是一个插件:首包资源查看优化工具(Eazy Build Size Optimization)
该插件通过Editor.log(这个文件会记录打包全过程日志,从日志中来过滤首包的资源内容)来查看首包资源包的内容,通过推荐的dll目录来查看首包代码包的内容。这样就避免了打Android包,以及一个工具搞定首包优化。
该插件链接:assetstore.u3d.cn/packages/to…
6. 总结
解决优化问题时,不要盲目优化,要做到有明确的指标,正确的方法,趁手的工具。有问题或者疑问的问题,欢迎大家评论,共同讨论共同进步。