性能优化(39)——发布优化——启动时间优化


 

  • 可分为两部分:启动到LOGO出现(Unity Pro版可以理解为自定义的Splash界面),LOGO出现到场景出现
  • 在移动平台上,IOS和安卓平台的启动流程是有差异的

IOS平台启动时间优化

  • Pre main过程:是通过一系列镜像二进制文件操作加载可执行文件、加载动态链接器、dyld(the dynamic link editor)、通过dyld递归加载所有动态链接库(dyLib)的过程,按苹果官方说法,就是分析镜像文件、映射镜像文件、设定并绑定镜像文件、镜像文件初始化这几个过程
  • Main()函数执行过程:主要包括UnityInitTrampoline、UnityInitRuntime,以及通过UIApplicationMain启动UnityAppController,并带动ios相应的controller、view之间的调用与回调,并在didFinishLaunchingWithOptions回调函数中做UnityInitApplicationNoGraphics初始化。其中UnityInitTrampoline函数中主要是crash reporter的初始化与新iosAPI对应的替换工作。而UnityInitRuntime主要做各种配置的读取,设置各种运行时参数,解析gfx设备相关参数与初始化Unity Player,并在此阶段初始化文件系统与各个运行时模块初始化和clear up的注册工作。而UnityInitApplicationNoGraphics主要是做mono或il2cpp以及虚拟机的初始化,PlayerInitEngineNoGraphics过程与创建UI闪屏,并做UIStatusBar初始化工作。
  • 到此为止,黑屏阶段结束,进入startUnity过程
  • ios main函数执行过程,可以通过查看导出的ios工程学习。但UnityInitRuntime以及UnityInitApplicationNoGraphics过程则需要有Unity引擎代码才能知道其中的细节
  • 以上三个ios启动的过程,Pre main与start Unity这两块是我们可以通过一些手段来优化的,而ios main函数执行过程与回调过程需要有引擎源码才能做深入优化

IOS平台程序启动需要注意的点

  1. 不同的ios系统程序启动的时间会因ios版本的不同而略有差异
  2. ios程序启动分为安装后首次启动、冷启动、热启动
  • 冷启动:杀掉程序后重新启动
  • 热启动:程序进入后台后再切回前台,一些资源和设备状态恢复的过程
  • 一般我们所说的启动优化是指优化冷启动
  1. 启动时间超过20秒的程序会被系统自动杀掉
  2. Unity默认竖屏程序比横屏程序启动时间略长,但这个差异一般情况下不明显
  3. 推荐Pre main过程耗费的时间最好不要超过400ms
  • 这个过程在IOS14之前的版本,可以通过开启DYLD_PRINT_STATISTICS或DYLD_PRINT_STATISTICS_DETAIL到环境变量,然后在控制台输出信息中查看
  • 但在IOS15版本以后,这个环境变量不起作用了,但可以借助XCode的Instruments Time Profiler查看整体的启动流程和时间消耗

IOS Pre Main阶段优化建议

  1. 要做镜像文件的瘦身动作,合并重复或删除用不到的一些代码
  • 针对Unity引擎,在IOS Player Setting下开启Strip Engine Code来减少Unity引擎库大小,如果是一些第三方库,可以通过App Code检测当前没有使用到的类和代码并删除
  1. 减少不必要的Framework与引用的动态链接库的加载
  2. 使用Static Archives链接dyLib
  3. C++代码中减少全局静态变量的使用,以及过度抽象,注意虚函数表的开销(一般超过10000个的虚函数库会有明显的加载开销)
  4. OC对象将在+load方法中要做的事延迟到+initialize方法中
  5. 减少OC对象的metadata。比如减少OC的Class、Selector以及Category的数量
  6. 在运行initializers中尽量不要调用dlopen,不要创建线程
  7. 注意一些第三方库与平台SDK。它们经常是造成黑屏时间长的主要问题

Andorid平台启动时间优化

Andorid平台程序启动需要注意的点

  1. 不同版本的Andorid系统程序启动时间略有差异
  2. Android启动分为首次启动、冷启动、热启动,一般我们所说的优化是指冷启动
  3. App进入后台可能会被系统自动杀掉,恢复也算冷启动
  4. Unity中Activity的andorid:launchMode属性一定要保证是SingleTask的,否则原生界面调出,或切到后台等都可能发生崩溃
  5. 通过adb logcat查看日志中Displayed标签来查看程序启动到显示前时间
  6. 通过Android Studio的Android CPU profiler工具来定位启动时瓶颈
  7. 通过GooglePlay的Android vitals来发现启动异常问题
  8. 一些三方库与平台SDK对启动时间的影响

Andorid启动优化建议

  1. 减少Activity onCreate函数中复杂的逻辑工作
  2. 将所有的资源初始化做Lazy Load放到不同的线程中,不要全部放到主线程中

ios下的start unity过程与Andorid下的start up过程的优化建议

  • 这个过程的优化完全可以在unity编辑器下完成