[iOS] 新規インストール時のアプリサイズを計測し、最適化を行なう方法について

2017.03.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは。モバイルアプリサービス部の平屋です。

本記事では、新規インストール時のアプリサイズを計測し、最適化を行なう方法を紹介していきます。

検証環境

  • macOS Sierra Version 10.12.3
  • Xcode Version 8.2.1

目次

  • アプリサイズを計測する
    • 各種生成物について
    • アプリサイズのレポートについて
    • iOS App Store固有の考慮事項について
    • ipaファイルのサイズの内訳をチェックする
  • アプリサイズを最適化する
    • コードの改善を検討する
    • アセットの改善を検討する
    • アプリのアーキテクチャの改善を検討する
  • さいごに

アプリサイズを計測する

アプリサイズの最適化作業を行う前に、現状のアプリサイズを計測します。はじめに計測しておくことで、サイズの変化量や最適化の影響を把握できるようになります。

また、アプリの配布プロセスの中で作られる各種生成物の内容や目的を理解することも重要です。

各種生成物について

配置される場所や目的ごとにいくつかの種類の生成物が存在します。

reducing-the-size-of-ios-app

アプリケーションバンドル

App Store提出用のipaファイル

  • App Storeへのアップロード、またはApp Store提出用のエクスポート時に生成される
  • このipaファイルは以下を圧縮したもの
    • アプリケーションバンドルを含むディレクトリ
    • App Storeのサービスのためのリソース
      • .dSYMファイルやオンデマンドリソースのアセットなど

ユニバーサルipaファイル

  • 圧縮されたアプリケーションバンドルのこと
    • アプリがサポートする全てのデバイスで動作させるために必要な全てのリソースを含む
  • Bitcodeは再コンパイルされる
  • App Storeのサービスのためのリソースは削除される
  • iOS 8以前のデバイスを使用してApp Storeからアプリをダウンロードする場合、このタイプのipaファイルがダウンロードされる

App Thinning済みのipaファイル

  • 圧縮されたアプリケーションバンドルのこと
    • 特定のデバイスで動作させるために必要なリソースだけを含む
  • Bitcodeは再コンパイルされる
  • App Storeのサービスのためのリソースは削除される
  • iOS 9以降のデバイスを使用してApp Storeからアプリをダウンロードする場合、このタイプのipaファイルがダウンロードされる

ユニバーサルアプリケーションバンドル

  • 「ユニバーサルipaファイル」が解凍されたもの
  • アプリのインストール処理の中で、ユニバーサルipaファイルが解凍され、ユニバーサルアプリケーションバンドルがデバイスにインストールされる

App Thinning済みのアプリケーションバンドル

  • 「App Thinning済みのipaファイル」が解凍されたもの
  • アプリのインストール処理の中で、App Thinning済みのipaファイルが解凍され、App Thinning済みのアプリケーションバンドルがデバイスにインストールされる

アプリサイズのレポートについて

Xcodeのエクスポート機能を使用してアプリサイズのレポートを出力できます。レポートを出力するには以下の操作を行います。

エクスポートが完了すると、出力先のフォルダの中に「App Thinning Size Report.txt」ファイルが存在することを確認できます。

「App Thinning Size Report.txt」ファイルには、各デバイスタイプに対する以下の値が記載されます。

  • 圧縮時状態のサイズ
  • 非圧縮状態のサイズ
  • オンデマンドリソースのサイズ

こちらのサンプルアプリから出力したレポートは以下の通りです。

App Thinning Size Report for All Variants of UserNotificationsUIDemoApp

Variant: UserNotificationsUIDemoApp-iPad 2-etc.ipa
Supported devices: iPad (3rd generation), iPad (4th generation), iPad 2, iPad mini, iPhone 4S, iPhone 5, iPhone 5c, and iPod touch
App + On Demand Resources size: 4.3 MB compressed, 9.3 MB uncompressed
App size: 4.3 MB compressed, 9.3 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed


Variant: UserNotificationsUIDemoApp-iPhone 7 Plus-etc.ipa
Supported devices: iPad (5th generation), iPad Air, iPad Air 2, iPad Pro (12.9-inch), iPad Pro (9.7-inch), iPad mini 2, iPad mini 3, iPad mini 4, iPhone 5s, iPhone 6, iPhone 6 Plus, iPhone 6s, iPhone 6s Plus, iPhone 7, iPhone 7 Plus, iPhone SE, and iPod touch (6th generation)
App + On Demand Resources size: 4.2 MB compressed, 9.2 MB uncompressed
App size: 4.2 MB compressed, 9.2 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed


Variant: UserNotificationsUIDemoApp.ipa
Supported devices: Universal
App + On Demand Resources size: 6.3 MB compressed, 16.5 MB uncompressed
App size: 6.3 MB compressed, 16.5 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed

アプリサイズのレポートを取得するための別の方法

xcodebuildコマンドでApp Thinning済みのipaファイルを作ることによって、アプリサイズのレポートを取得する方法もあります。

iOS App Store固有の考慮事項について

Xcodeのレポートに記載される「Thinning Size」は、アプリの最終的なサイズを概算したものであり、最終的なサイズは、アプリのレビューが通った後にiTunes Connect上で確認できます。

App Storeが「ユニバーサルipaファイル」や「App Thinning済みのipaファイル」生成するタイミングで、ipaファイル内の全てのバイナリは暗号化されます。

暗号化によってバイナリのサイズは変更されません。しかし、暗号化されたバイナリは効率的に圧縮できなくなるため、レポートに記載される概算サイズよりも大きくなります。「暗号化されたバイナリは効率的に圧縮できない」のは、App Storeの暗号化アルゴリズムに固有のものではなく、強力な暗号化アルゴリズムによる結果の1つのようです。

ipaファイルのサイズの内訳をチェックする

「ユニバーサルipaファイル」や「App Thinning済みのipaファイル」のサイズが予想よりも大きい場合、App Thinning済みのアプリケーションバンドルを調べて、その中のどのファイルが最大の容量を占めるかを確認します。( 「App Store提出用のipaファイル」のサイズは、実際にデバイスにインストールされるアプリサイズとは異なるので、この検査では使用すべきではない)

ipaファイルはただのzipアーカイブなので、以下の方法でアプリケーションバンドルの内訳を確認できます。

  • .ipaファイルの拡張子を.zipに変更し、Finderで解凍する
  • 解凍されたアプリケーションバンドルを右クリックし、「パッケージ内容を表示」を選択して、内部のリソースを表示する

また、unzip -lv /path/to/your/thinned_app.ipaコマンドを実行することによって、ipaファイル内の各項目の圧縮サイズを調べることができます。

$ unzip -lv /path/to/UserNotificationsUIDemoApp-iPhone\ 7\ Plus-etc.ipa
Archive:  /path/to/UserNotificationsUIDemoApp-iPhone\ 7\ Plus-etc.ipa
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       0  Stored        0   0% 03-22-2017 17:03 00000000  Payload/
       0  Stored        0   0% 03-22-2017 17:05 00000000  Payload/UserNotificationsUIDemoApp.app/
       0  Stored        0   0% 03-22-2017 17:03 00000000  Payload/UserNotificationsUIDemoApp.app/_CodeSignature/
   23731  Defl:N     4496  81% 03-22-2017 17:05 37b3f087  Payload/UserNotificationsUIDemoApp.app/_CodeSignature/CodeResources
     418  Defl:N      253  40% 03-22-2017 17:03 53eb824f  Payload/UserNotificationsUIDemoApp.app/archived-expanded-entitlements.xcent
       0  Stored        0   0% 03-22-2017 17:03 00000000  Payload/UserNotificationsUIDemoApp.app/Base.lproj/
       0  Stored        0   0% 03-22-2017 17:03 00000000  Payload/UserNotificationsUIDemoApp.app/Base.lproj/LaunchScreen.storyboardc/

... (省略) ...

--------          -------  ---                            -------
 9179223          4174496  55%                            82 files

任意のリソースのサイズを大きく減らすことはできても、圧縮後のサイズは劇的に変化しないかもしれません。

ipaファイルのサイズを縮小する最も効果的な方法は、不要なリソースを削除することです。

アプリサイズを最適化する

現状のアプリサイズや、サイズの内訳などを把握できたら、アプリサイズを最適化していきます。

コードの改善を検討する

外部ファイルに移動可能なデータは外部ファイルに移動する

  • 長い文字列やテーブルなどのリソースをコードから外部ファイルに移動すると、効率的に圧縮されるため、最終的なダウンロードが小さくなる
    • 技術的背景については「iOS App Store固有の考慮事項」を参照

コンパイラオプションを確認する

  • リリースビルドの最適化レベルの設定を「Fastest、Smallest [-Os]」に設定する
    • コンパイルされたバイナリのサイズが大幅に小さくなる
    • この設定は、Xcodeプロジェクトの「リリース」設定のデフォルト

アセットの改善を検討する

不要なリソース、圧縮できそうなリソースなどがないかを探します。

不要なリソースがないかチェックする

  • 「ipaファイルのサイズの内訳をチェックする」で説明している手順を使用して、実際にアプリケーションバンドルに含まれているものを確認する
  • アプリケーションには、READMEのような不要なファイルが含まれていることがよくある

アセットカタログを活用する

  • 画像、テクスチャ、データアセットにアセットカタログを使用する
    • 各アセットに関連するメタデータをタグ付けして、アセットの対象となるデバイスを指定する
    • アセットカタログは、App Slicingによって提供されるサイズの縮小を最大限に活用する
    • これは、すべてのデバイスで必要とされないアセットを持つアプリにとっては重要なこと
    • App Thinning in Xcode - WWDC 2015 - Videos - Apple Developer
  • 各アセットタイプごとに圧縮レベルを設定することができる
  • サイズ変更可能な中央領域を定義し、画像のサイズを縮小することができる

可能であれば8ビット画像を使用する

  • 32ビットのPNGの代わりに8ビットのPNGを使用すると、イメージのサイズを1/4にできる
    • 8ビット画像は256色のみを有するので、写真などの画像には適さないかもしれない
    • グレースケール画像や色数が少ない画像の場合は、効果があるかもしれない

できるだけ画像を圧縮する

  • 32ビットイメージの場合、Adobe Photoshopの「Web用に保存」機能を使用すると、JPEGおよびPNGイメージのサイズを大幅に縮小できる

オーディオを圧縮する

  • Audio Development for Games - WWDC 2011 - Videos - Apple Developer
  • 原則として、AACまたはMP3を使用してオーディオを圧縮し、ビットレートを下げることを試したほうがよい
    • 44.1khzのサンプルレートは過度であることが多い
    • 低いビットレートのクリップでは品質はあまり低下しない

アプリのアーキテクチャの改善を検討する

次に紹介する方法は他よりも規模が大きめです。実践するにはアプリのアーキテクチャを変更する必要があります。

オンデマンドリソースを採用する

  • アプリケーションで使用するすべてのリソースを分析する
    • 頻繁に使用されないリソースや一部のユーザーのみが使用されるリソースを特定する
    • これらのリソースをオンデマンドリソースで配信されるアセットパックにグループ化する
  • On-Demand Resources Guide: On-Demand Resources Essentials

Background Downloadsを採用する

  • 可能であれば、NSURLSessionによって提供されるバックグラウンドセッションを使用して、Webサービスからアセットをダウンロードするようにする

さいごに

本記事では、新規インストール時のアプリサイズを計測し、最適化を行なう方法を紹介しました。

各種生成物の役割やアプリサイズ最適化の手法を整理することができました!

アプリのアップデート時のダウンロードサイズを減らす方法については以下のQ&A記載されているようです。

参考資料