Slide 1

Slide 1 text

App Size Optimization 
 への挑戦 by nade / @kazuma_nagano

Slide 2

Slide 2 text

Kazuma Nagano kazumanagano kazuma_nagano CyberAgent, Inc.

Slide 3

Slide 3 text

アプリサイズコントロールできてますか?

Slide 4

Slide 4 text

アプリサイズによるユーザー影響 インストール時 • データ通信量の制限 • ⽇中の速度低下 
 ダウンロードが全く終わらない → キャンセル 
 インストールしたことを忘れる → 起動しない 広告効果の影響 • ダウンロード→起動での離脱が増える • ストア→インストールでのコンバージョン率と⽐較して、 
 広告sdk側で計上される成果数が落ちる

Slide 5

Slide 5 text

アプリサイズによるユーザー影響 アンインストール数 • ⼤きいアプリからアンインストールされる傾向 • iOS 1 1 〜「⾮使⽤のAppを取り除く」 
 ストレージが不⾜している状態から再インス トールしてもらう壁

Slide 6

Slide 6 text

174 . 2 MB → 127 . 6 MBへと26.8%の削減 Size Over Time of Tapple 150 MB Limit 
 2017 - 20 1 9 100 MB Limit 
 2013 - 20 1 7 200 MB Limit 
 2019 -

Slide 7

Slide 7 text

今回話したいこと • 私たちがどういったことを⼿順、考えでアプリサイズを削減していったか? • アプリサイズ削減にはどういった打ち⼿があるのか? • コスパの良かった打ち⼿はなんだったのか?

Slide 8

Slide 8 text

1 .背景 2 .アプリサイズの計測 3 .IPAの内部を確認する 4 .Archive Option 5 .Resource fi les 6 .Others 7 .まとめ 8 .参考⽂献

Slide 9

Slide 9 text

アプリサイズの計測

Slide 10

Slide 10 text

アプリサイズの計測 https://developer.apple.com/documentation/xcode/reducing-your-app-s-size

Slide 11

Slide 11 text

どの⽣成物を計測すべきか?

Slide 12

Slide 12 text

⽣成物の種類について アプリケーションバンドル(*.app) • アーカイブ時に⽣成される「*.app」ファイルのこと • アプリが正常に動作するために必要なすべてのものを含む App Store⽤IPA • AppStoreへのアップロード、AppStore提出⽤のアップロード時に⽣成 • 各端末⽤のすべてのバンドル、.dSYM等のApp Store⽤のメタデータが圧縮されたもの 端末⽤IPA • ユニバーサルIPA(〜iOS 8 )もしくはApp Thinning済みのIPA(iOS 9 〜) • Bitcodeは再コンパイルされ、アセットも各端末⽤に最適化される • App Storeのサービスのためのリソースは削除される https://dev.classmethod.jp/articles/reducing-the-size-of-ios-app/

Slide 13

Slide 13 text

⽣成物の種類について https://dev.classmethod.jp/articles/reducing-the-size-of-ios-app/

Slide 14

Slide 14 text

ユーザーが⽬にするアプリサイズ

Slide 15

Slide 15 text

アプリサイズの計測 • デバッグ⽤に作成したバイナリやAppStore⽤IPAはサイズ測定に適してない dSYMや全ての端末のアセットが含まれており、端末ごとの最適化もされてない • ユーザーへのパフォーマンスは端末⽤IPAで⽐べる必要がある ※ AppStoreに表⽰されるサイズは実際のインストール時のアプリサイズとズレがある(バグ?)

Slide 16

Slide 16 text

アプリサイズの確認

Slide 17

Slide 17 text

リリース済みアプリのサイズを確認する • App Store ConnectのTest Flight > ビルド セクションから確認できる • Apple公式⽈く最も正確なサイズ • ダウンロードサイズとインストールサイズが提供されている

Slide 18

Slide 18 text

開発中アプリのサイズを確認する • XcodeのレポートツールでApp Size Reportを作成できる ⼿順 1 . XcodeでアプリをArchive 2 . Ad Hoc, Development, or EnterpriseとしてExport 3 . オプション設定でApp Thinningに“All compatible device variants” 
 “Rebuild from Bitcode”にチェックする 4 . 証明書を選んでアプリをExportする 5 . 作成されたフォルダ内の “ App Thinning Size Report.txt”を確認する

Slide 19

Slide 19 text

App Thinning Size Report for All Variants of ExampleAp p Variant: ExampleApp.ip a Supported variant descriptors: [device: iPhone11,4, os-version: 12.0], [device: iPhone9,4, os-version: 12.0], [device: iPhone10,3, os-version: 12.0], [device: iPhone11,6, os-version: 12.0], [device: iPhone10,6, os-version: 12.0], [device: iPhone9,2, os-version: 12.0], [device: iPhone10,5, os-version: 12.0], [device: iPhone11,2, os-version: 12.0], and [device: iPhone10,2, os-version: 12.0 ] App + On Demand Resources size: 6.7 MB compressed, 18.6 MB uncompresse d App size: 6.7 MB compressed, 18.6 MB uncompresse d On Demand Resources size: Zero KB compressed, Zero KB uncompresse d // Other Variants of Your App . App Thinning Size Report.txt

Slide 20

Slide 20 text

ԼهͷεΫϦϓτʹͯϫϯϥΠφʔͰApp Size ReportΛੜ੒Մೳ
 ※ OptionsPlist.plistʹ ΛؚΊΔඞཁ͋Γ
 ※ Ұ౓खಈͰߦ͍ɺੜ੒͞ΕͨOptionsPlist.plistΛར༻͢Δ͜ͱ͕ਪ঑ 
 $ xcodebuild -exportArchive -archivePath iOSApp.xcarchive -exportPath Release/ MyApp -exportOptionsPlist OptionsPlist.plist CIでApp Size Reportを⽣成する

Slide 21

Slide 21 text

IPAの内部を確認する

Slide 22

Slide 22 text

IPAの内部を確認する ipaファイルの実体はzipファイルなので解凍して内部を確認できる ⼿順 1 . Finderで対象のipaファイルを開く 2 . 拡張⼦をipaからzipに書き換えて解凍 3 . 解凍されたアプリバンドル右クリックし、 “パッケージの内容を表⽰”

Slide 23

Slide 23 text

不要なファイル、リソースを確認する • README.md • Swiftlint, SwiftGenといったtoolのバイナリ • デバッグアプリ⽤のモジュール、リソース • その他本番では不要なAssetsなど

Slide 24

Slide 24 text

さらにアプリバンドル内のバイナリ を解析する

Slide 25

Slide 25 text

アプリバンドル内のバイナリを解析する • 解凍ファイルの中⾝を⾒ただけでは⽣成されたバイナリがなぜ⼤きいのかわ からない • バイナリ内のリソースを最適化してもどの程度効果があったのかわからない

Slide 26

Slide 26 text

Bloaty: a size pro fi ler for binaries https://github.com/google/bloaty • Google製のバイナリサイズ プロファイラ • CLI Application • M 1 Macでも動作 • ELF, Mach-O, PE/COFF, WebAssemblyに対応(⼀部experimental) • Size di f を取る機能もある

Slide 27

Slide 27 text

$ bloaty Frameworks/Umbrella.framework/Umbrella FILE SIZE VM SIZE -------------- -------------- 67.9% 7.74Mi 67.0% 7.74Mi __TEXT,__tex t 5.1% 599Ki 5.1% 599Ki Export Inf o 3.2% 373Ki 3.2% 380Ki [38 Others ] 3.1% 358Ki 3.0% 358Ki __DATA,__cons t 3.1% 357Ki 3.0% 357Ki String Tabl e 2.7% 320Ki 2.7% 320Ki __TEXT,__gcc_except_ta b 2.6% 309Ki 2.6% 309Ki __TEXT,__cons t 1.8% 206Ki 1.7% 206Ki __TEXT,__cstrin g 1.6% 184Ki 1.6% 184Ki __TEXT,__unwind_inf o 1.4% 162Ki 1.4% 162Ki __DATA,__objc_cons t 1.3% 146Ki 1.2% 146Ki __TEXT,__objc_methtyp e 0.0% 0 1.2% 146Ki __DATA,__bs s 1.2% 141Ki 1.2% 141Ki __DATA,__dat a 0.9% 108Ki 0.9% 108Ki Symbol Tabl e 0.9% 108Ki 0.9% 108Ki Code Signatur e 0.9% 99.5Ki 0.8% 99.5Ki __TEXT,__eh_fram e 0.5% 58.5Ki 0.5% 58.5Ki Function Start Addresse s 0.5% 57.8Ki 0.5% 57.8Ki __DATA,__objc_dat a 0.5% 55.1Ki 0.5% 55.1Ki Weak Binding Inf o 0.5% 53.2Ki 0.5% 53.2Ki Lazy Binding Inf o 0.4% 46.0Ki 0.4% 46.0Ki Binding Inf o 100.0% 11.4Mi 100.0% 11.5Mi TOTAL Bloaty: a size pro fi ler for binaries

Slide 28

Slide 28 text

Archive Option

Slide 29

Slide 29 text

App Thinning • IPAに特定のデバイスで動作させるために必要なリソースだけを含まれるよう にする技術 • Archive後のオプション設定でApp Thinning項⽬に 
 “All compatible device variants”を設定することで有効に

Slide 30

Slide 30 text

App Thinning • IPAに特定のデバイスで動作させるために必要なリソースだけを含まれるよう にする技術 • Archive後のオプション設定でApp Thinning項⽬に 
 “All compatible device variants”を設定することで有効に TappleではFastlane経由で特に意識せずIPAを作成していたところオフになっ ていた😇

Slide 31

Slide 31 text

for_lane :archive_and_submit_ipa d o scheme 'app ' export_method 'app-store ' configuration 'Release ' codesigning_identity 'codesigning_identity ' export_options( { thinning: "" , provisioningProfiles: { "com.example.bundleid" => "Provisioning Profile Name " } } ) en d App Thinning -Fastlane Gym fi le

Slide 32

Slide 32 text

Enable Bitcode • アプリを再コンパイルしてサイズを縮⼩できるようにする技術 • Bitcodeはコンパイルされたプログラムの中間表現のこと • Bitcodeを含めることでアプリがAppStoreで再びコンパイル、リンクされる • アプリバンドル内のすべてのアプリとFrameworkにBitcodeを含める必要が ある( ENABLE_BITCODE = YES を設定) https://help.apple.com/xcode/mac/ 11 . 0 /index.html?localePath=en.lproj#/devde 46 df 08 a

Slide 33

Slide 33 text

2021/9/5現在)AppStore ConnectからdSYMをダウンロードする必要あり • fastlaneにdownload_dSYMがあるがAppStore Connect Keyに対応してないため注意 Enable Bitcode for Crashlytics https:// fi rebase.google.com/docs/crashlytics/get-started?platform=ios

Slide 34

Slide 34 text

Resource Files

Slide 35

Slide 35 text

Asset Catalogs 画像、テクスチャ、データアセットはAsset Catalogsを採⽤する • メタデータをタグ付けして、アセットの対象となるデバイスを指定する • サイズ変更可能な中央領域を定義し、画像のサイズを縮⼩できるようにする • 各アセットタイプごとに圧縮レベルを設定する

Slide 36

Slide 36 text

Image Format • ベクター、ラスター画像の適切な使い分け • PNGの場合32ビッドではなく8ビッドを利⽤すると1/4に • PNGの代わりにより圧縮の効くHEIFを採⽤すると⼩さくなる傾向 • ベクター画像にXcode 12 (iOS 13 〜)で利⽤可能なsvgを採⽤するとpdfと⽐ 較し⼩さくなる傾向(最⼤1/10程度)

Slide 37

Slide 37 text

Image Compression • 32ビッドPNGの場合AppleはPhotoshopの「Web⽤に保存」を推奨 
 ImageOptim https://github.com/ImageOptim/ImageOptim • ロスレスのイメージ最適化ツール • 内部ではZop fl i, PNGOUT, OxiPNG, JPEGOptim, SVGO等のツールを組み合わせて動いている • GUI • M 1 Macでも動作 https://help.apple.com/xcode/mac/ 11 . 0 /index.html?localePath=en.lproj#/devde 46 df 08 a

Slide 38

Slide 38 text

On-Demand Resources • App Storeでホストされ、アプリインストール後の任意のタイミングでダウ ンロードすることができるリソース • 使⽤頻度の低いリソースに対する利⽤を推奨 
 eg) 期間の限定された機能、アプリ内購⼊のリソース https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide

Slide 39

Slide 39 text

Others

Slide 40

Slide 40 text

コンパイルのサイズ最適化オプション • プロジェクトによって変化が⼤きく変わるため試してみるしかなそう コードコンパイル最適化 
 Swift Compiler - Optimization Level 
 
 Apple Clang - Optimization Level 
 SWIFT_OPTIMIZATION_LEVEL: -OSizeʢOptimize for Size [-O]ʣ Optimize Compile Option GCC_OPTIMIZATION_LEVEL: sʢFastest, Smallest [-Os]ʣ

Slide 41

Slide 41 text

Assetのサイズ圧縮の最適化 ASSETCATALOG_COMPILER_OPTIMIZATION: space Optimize Compile Option

Slide 42

Slide 42 text

debugConfigurations = ['Debug', 'Debug_etp', 'Release_adhoc', 'Release_etp' ] post_install do |installer | installer.pods_project.targets.each do |target | target.build_configurations.each do |config | if debugConfigurations.any? {|i| config.name.include?(i) } config.build_settings['GCC_OPTIMIZATION_LEVEL'] = '0 ' config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Onone ' els e config.build_settings['GCC_OPTIMIZATION_LEVEL'] = 's ' config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = ‘-Osize ' en d en d en d en d Optimize Compile Option - Pod fi le

Slide 43

Slide 43 text

External Framework / Module • なるべく純正のアプリケーションを使う 
 RxSwift → Combine 
 Realm → CoreData • 複数ターゲットに対してStatic Linkしていないか

Slide 44

Slide 44 text

まとめ

Slide 45

Slide 45 text

• まずは計測してみる • 計測が定常的に⾏われる仕組みをつくる • ⾃分たちのサービスにできる最適化を知る 
 ⼤きくなってしまった場合に棚卸し まとめ 優先度⾼(コスト低 / 効果⾼) • App Thinning • 不要なファイルの確認‧削除 • リソース管理をAsset Catalogに • Optimize Compile Option • Image Format • Image Compression • Frameworkの純正化 • On-Demand Resource • Enable Bitcode 優先度低(コスト低 / 効果⾼)

Slide 46

Slide 46 text

参考⽂献

Slide 47

Slide 47 text

参考⽂献 • Reducing Your App’s Size 
 https://developer.apple.com/documentation/xcode/reducing-your-app-s- size • Doing Basic Optimization to Reduce Your App’s Size 
 https://developer.apple.com/documentation/xcode/doing-basic- optimization-to-reduce-your-app-s-size • Doing Advanced Optimization to Further Reduce Your App’s Size 
 https://developer.apple.com/documentation/xcode/doing-advanced- optimization-to-further-reduce-your-app-s-size

Slide 48

Slide 48 text

参考⽂献 • [iOS] 新規インストール時のアプリサイズを計測し、最適化を⾏なう⽅法につ いて 
 https://dev.classmethod.jp/articles/reducing-the-size-of-ios-app/ • Cutting Binary Size on a Growing App 
 https://speakerdeck.com/line_devday 2 019 /cutting-binary-size-on-a- growing-app