iOSアプリの启动速度を2倍にするために,复数のDynamic FrameworkをStaticひ,ひとつのDynamic Frameworkを作るwith Swift

iOSカiOSエンジニアのmuukii(Twitter)です🥃

私人が开発を担当しているPairs Global(Pairsの海外向アプリ)はアプリの起动がとても遅いのです。

一体なぜなのか。

OSはアプリを启动してAppDelegate(厳密にはmain关数)が呼び出されるまでには様々な处理を行います。
起动の部分の处理を最适化することでアプリが起动していない状态からの起动の高速化が期待できます。

アプリ起动高速化のための初始き(长め)

には,用语について,厳密にはFrameworkとLibaryは异なるものですが,性质は近いので本记事では次のように用语を用います。

静态框架または静态库をめてとめて「静态框架」と呼びます
Dynamic Frameworkまたは动态库をまとめて“ Dynamic Framework”と呼びます。

OSはアプリを启动してAppDelegate(厳密にはmain关数)が呼び出されるまでには様々な处理を行います。
起动の部分の处理を最适化することでアプリが起动していない状态からの起动の高速化が期待できます。

起动までにどのような处理が行われているのかはWWDCの资料で知ることができます。

启动时间(应用启动时间)の最适化

优化应用启动时间– WWDC 2016 –视频– Apple Developer
启动应用程序是一个复杂而微妙的过程,并且会影响不同应用程序设计的启动时间。… developer.apple.com

今回取り组みたいことは起动时间に含まれる动态框架の动的リンク时间の削减です。

WWDCの资料ではdylibは使用は高価であり少ないほど良いと示しています。

あまり具体的な话はここでは触れませんが,つまりは模块を动态框架ではなく静态框架としてビルしてビ使用することで起动时间の最适化が可能ということです。

しかし,Swiftの登场以降模块を使用する上では动态框架の使用を避けることは难しいことでした。
XcodeがSwiftを含むコードベースを静态框架としてビルドすることに対応していなかったからです。

codeの问题はXcode10では解消されており,静态框架または静态库としてビルドすることが可能になっています。

迦太基のドキュメントでも起动时间の高速化について検讨て検アイデアが掲载されています。

迦太基/迦太基
Cocoa的简单,分散式依赖管理器– Carthage / Carthage github.com

では,动态框架を利用するメリットは何かと言うと,
実行可能なTargetが复数ある场合において,ソースコードを共有するケースです。

具体的にはアプリ本体とApp Extensionなどが挙げられます。

ざっくりとした说明にしておきますが,次のような构成だとします。

  • 应用程序(可执行)1MB
  • 扩展名(可执行)1MB

これらに共通のコードを使用したい场合,共通のコードを一绪にコンパイルしても良いですが,Moduleとして包むことでInternalのメソッド呼ド出しを防ぐなどの疎结合性を保つことが可能になります。

なので,MyCoreというModuleを用意します。

  • MyCore 1MB

MyCoreが静态框架だと中身(シン宝ボ)が可执行目标と合体するので,各サイズが次のようになります。

  • 应用程序(可执行)+ MyCore(静态框架)= 2MB
  • 扩展(可执行)+ MyCore(静态框架)= 2MB

からダウAppStoreからダウンロードするときには4MBの転送が必要になります。

をMyCoreを动态框架にすると,中身(シン宝シ)は合体せずにアプリ起动时に结合されるので,构成は次のようになり,

  • 应用程序(可执行)1MB
  • 扩展名(可执行)1MB
  • MyCore 1MB

合计サイズは3MBで済むことになります。

がのようにすることでリソースサイズの削减が可能となります。

UIと身近な例でいうとUIKit.frameworkはアプリにバンドルされていません。
これもアプリ起动のタイミングに动的に结合してアプリが立が上がっているのです。

を,実行可能ファイルがどんな动态框架を必要としているかはotoolを用いて调べることができます。

実行可能ファイルが必要とする动态框架を调べる

Xcodeプロジェクトでビルドを行うと商品フォルダからビルドによる成果物にアクセスができるようになります。

伞ファイルが実行可能ファイルです。

tool`otool`に渡してみます。

otool -Lで动的リンクを行う动态框架の一覧が表示されます。
UIKit.frameworkも対象であることが読み取れます。

またfileコマンドというものもあります。

と,64位x86_64用の可执行文件ファイルであるということがわかります。
Xcodeでシミュレータ用にビルドしているのでx86_64となっています。

Mach-Oとは実行ファイルのフォーマットです

Mach-O –维基百科
NEXTSTEP由来し,macOSで标准のバイナリファイルフォーマットとして采用されている 。ja.wikipedia。