SwiftyNote

主にSwiftな技術ブログ

【iOS】アプリ起動時間の最適化及び計測方法

アプリが立ち上がり使用できるようになるまでの時間をどのようにすれば最適化できるかというセッションでWWDC2016でAppleOptimizing App Startup Timeという動画がでている。聞いた限りここで紹介されている内容は2017年現在でも変わらず有効なように聞こえる。 ここではdyldなどの動的なローダの内部的な詳細などについてやアプリの起動時間の最適化に関するベストプラクティスが述べられている。

さて、まずはじめに、どのようにアプリの起動時間を計測して、なにを基準に最適化を目指すかという問題がある。 これについてAppleは起動時間については400ms未満で立ち上がることを推奨している。(アプリの起動時間をテストするときには、できるだけ性能の高いデバイスを基準として計測すること)

では、どのように起動時間を計測するかというと、XCode付属のTime ProfilerXCode環境変数を使うことでアプリの起動時間とそれに寄与しているステップを把握することができる。

まずTime Profilerではアプリの初期化時間、起動時間、ボトルネックとなっている関数の割り出しなどが可能で、100000分の1秒単位で計測できる。

使い方はXCodeのメニューからInstrumentを開きTime Profilerを選択する。 f:id:rinov:20170924223559p:plain

起動後は再生ボタン横のところで端末とアプリを選択して再生をすると、自動で当該アプリが起動されLife Cycleというグラフ上にInitializingLaunchingという計測時間結果が表示される。 Initializingはアプリを起動するまでに行われるPre-Main timeや依存関係のロードの時間を表し、Launchingはアプリ自体を立ち上げるために掛かった時間を表している。つまりユーザがアプリアイコンをタップしてからアプリを使えるようになるまでの起動時間はInitializing+Launchingの値ということになる。

ほとんどの場合Initializingの時間のほうが掛かってしまうが、これはアプリを起動するために必要なフレームワークなどの依存関係の読み込みが全てこのステップで行われるからであり、CarthageCocoapods等を全く使用していないアプリにおいても内部で使用されている標準フレームワークのロードなどが行われる。

では一番起動時間に関わっている動的ローディングの部分は実際にどのくらい時間がかかっているかを計測する方法もある。それはXCode環境変数DYLD_PRINT_STATISTICSを追加することで取得できる。

f:id:rinov:20170924225740p:plain

[出力例]

Total pre-main time:  56.23 milliseconds (100.0%)
       dylib loading time:  37.23 milliseconds (66.2%)
      rebase/binding time:   6.81 milliseconds (12.1%)
          ObjC setup time:   8.16 milliseconds (14.5%)
         initializer time:  13.19 milliseconds (23.4%)
         slowest intializers :
           libSystem.dylib :   5.22 milliseconds (9.2%)

このようにdylibのロード時間が最も起動時間に寄与していることがわかる。 では、次にこのdylibのロード時間を短縮・最適化する方法については、Appleは以下のことを推奨している。

  • Appleのシステムフレームワークの読み込みは高度に最適化されているが、組み込みフレームワークは時間が掛かってしまう。そのためdylibの読み込み時間を減らす方法は、いくつかの組み込みフレームワークを合併させるか、そもそも組み込みフレームワークを減らすという手段がある。また、非システムフレームワークでは多くても6個までが良いとされている。

  • 多数のObjective-Cクラスやセレクターなどは起動時間を遅くする(SwiftのStructなどは高速)

  • ObjcのついているものはObjective-Cのランタイムが必要ということでクラス・カテゴリの登録や使用するセレクターの一意化が必要となり、リベース/バインディングのステップで時間がかかるため、Objcを減らすことでも起動時間の短縮に繋がる。

参考:

developer.apple.com