Skip to content

首场景启动优化

提升Unity WebGL游戏启动速度章节我们提到过:

在timelog中呈现的首场景耗时即为引擎初始化与开发者首帧逻辑,关于该阶段耗时,开发者需要注意的是:

  1. MonoBehaviour脚本的首帧Start/Awake应足够少逻辑,优先将画面呈现
  2. 初始场景不宜过大,通常呈现Splash场景即可
  3. 初始场景中需要后续主场景或配置加载时可采取分帧策略,切勿在Start/Awake阻塞

下面介绍如何通过在小游戏下通过Profile的方式对小游戏首场景耗时进行针对性优化。

小游戏Profile

微信小游戏在安卓平台提供了CPU Profile能力,使用姿势为: 1.采集Profile: 点击右上角菜单 -> 开发调试 -> Start CPU Profile -> Stop CPU Profile; 2.导出Profile文件 当点击Stop CPU Profile之后,会弹出浮窗告知profile文件的存储路径,通过USB链接电脑或者第三方文件管理器即可将Profile文件传输至电脑。

3.Chrome导入Profile文件 打开Chrome浏览器,右键审查元素或者按F12即可打开控制台界面。选中JavaScript Profile tab(如果默认没有,可能在右上角的三个点展开菜单->More tools里面),点击load导入步骤2的profile文件,Profile文件的使用可以参考Google的开发文档: https://developers.google.com/web/tools/chrome-devtools/rendering-tools/js-execution

Unity CallMain

参考文档小游戏启动流程中提到的,当游戏代码包下载编译完成和首包资源下载完成后会运行游戏逻辑,最开始执行的逻辑是CallMain主函数。 在WebGL模式下,CallMain的主要是initWebGLPlayer调用,主要分成两部分调用:

  • Unity引擎初始化:主要分成:InitializeIl2CppFromMain、RuntimeInitialize、PlayerInitEngineNoGraphics和PlayerInitEngineGraphics等函数调用;
  • 首场景初始化:PlayerLoadFirstScene函数调用;

下表为针对Unity Benchmark项目在不同设备上的callmain耗时分析,Benchmark项目链接:https://github.com/Unity-Technologies/Benchmark

下面实验均采用Unity 2018.4.24f1版本,Development模式会对性能有一定影响,下表数据均为Development模式下数据。

initWebGLPlayer主要函数安卓魅族6sOPPO A37m安卓小米10开发者工具
InitializeIl2CppFromMain525ms954ms113ms39.90ms
RuntimeInitialize139ms649ms50.2ms2.33ms
PlayerInitEngineNoGraphics463.8ms1.24s154ms10.46ms
PlayerInitEngineGraphics1.4s2.94s403ms126ms
PlayerLoadFirstScene815ms2.12s213ms70.75ms

目前为止,开发者可以操作的主要是PlayerLoadFirstScene函数的调用,参照Unity的Benchmark项目,要尽可能将PlayerLoadFirstScene的耗时控制在整个CallMain耗时的左右,如果CallMain耗时过大,可以借助上面提到的Profile工具进行优化,下面简单分析流程。

CallMain Profile分析

1.改造小游戏代码 因为安卓采集Profile文件需要手动控制,而CallMain会在码包下载编译完成和首包资源下载完成后就执行,为了录制启动阶段完整的Profile,需要保证Profile的录制开始之后才真正执行游戏开始逻辑,找到项目的game.js文件,改造最后几行即可:

js
// gameManager.startGame();

wx.onTouchStart((result) => {
  console.log('真正执行开始游戏逻辑');
  gameManager.startGame();
})

GameGlobal.manager = gameManager;

通过上面的改造,在进入小游戏后,可以按照这个流程采集Profile:Start CPU Profile -> 点击屏幕触发真正的开始游戏逻辑 -> 看到游戏界面后Stop Profile。

2.导入步骤1的启动过程Profile文件

导入文件后,我们只需要关注CallMain调用的PlayerLoadFirstScene函数,如果PlayerLoadFirstScene耗时占比过高,大多是因为在首场景执行了不必要的操作,比如大量反序列化操作、配置解析操作,按需剔除后再次Profile即可验证效果。

Released under the MIT License.