团结引擎小游戏平台新增了 Extreme 级别的托管代码剪裁策略,基于对MonoBehaviour和ScriptableObject类深入静态分析,尽可能多的剔除代码。
托管代码精简可以缩减构建后的托管程序集的大小,进而减少wasm包的大小,因此对于 il2cpp backend 优化效果较明显。 对于 .net 8 backend 则作用不大,因为托管程序集本身体积就不大,缩减的收益不大。
Managed Code 剔除会对代码进行静态分析。首先依据 root marking rules 标记root类型、方法、属性等,然后再依据 dependency marking rules 去标记这些root的依赖。接下来未被标记的代码会被剔除。新增的 Extreme Level,使用了更加激进的标记规则,与 High Level 对比如下:
在依赖标注上:
在4个不同规模的项目上实测的剔除效果对比如下:
与 High Level 一样,基于静态分析的 Extreme 模式也存在误剔除的风险。为此我们新增了 Dryrun 模式,可帮助开发者快速定位与收集误剔除的方法。
例如微信 SDK 组件挂载问题:某些类型如 WXProfileStatsScript 通过 AddComponent(Type) 挂载,由于类型变量在其他地方赋值,编译时无法确定,导致该类型无法保留。Dryrun 模式下,将打印相应的警告:
补充信息:AddComponent<Type >() 和 AddComponent(typeof(XXX)) 模式的调用则可以通过代码上下文来识别,因此可以被保留。
另一个案例 LitJson 库反射问题:LitJson 库通过反射查找类型的 public 属性。在进行 Managed Code 剔除时,由于通过静态分析无法得知类型的哪些 public 属性将被反射调用,可能导致这些属性的 get/set 方法被误剔除。
注意:只有 il2cpp backend 才支持此模式。.net 8 backend 下此模式不显示。