Skip to content

Latest commit

 

History

History
61 lines (46 loc) · 4.37 KB

FirstSceneOptimization.md

File metadata and controls

61 lines (46 loc) · 4.37 KB

首场景启动优化

提升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主要函数 安卓魅族6s OPPO A37m 安卓小米10 开发者工具
InitializeIl2CppFromMain 525ms 954ms 113ms 39.90ms
RuntimeInitialize 139ms 649ms 50.2ms 2.33ms
PlayerInitEngineNoGraphics 463.8ms 1.24s 154ms 10.46ms
PlayerInitEngineGraphics 1.4s 2.94s 403ms 126ms
PlayerLoadFirstScene 815ms 2.12s 213ms 70.75ms

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

CallMain Profile分析

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