<-- mermaid -->

iOSアプリ起動高速化に挑戦!不要コードやリソースの見直しとライブラリのstatic化編

みなさんこんにちは。NewsPickでiOSアプリの開発をしている森崎です。
当記事ではどのアプリも一度は見直しを検討したことがあるであろう、アプリの起動時間の高速化についてお話しします。 他の記事で起動時の処理や高速化への改善策を書いたので、ここでは具体的に行ったこととその結果を数字とともに書きたいと思います。

⬇️起動時の処理や高速化への改善策を書いた記事です。
こちらを読んでもらうと、当記事の内容がより理解できると思います。(読まなくてももちろんわかります!)

qiita.com

今回はSystem Interface Initializationの箇所の見直をしました。(⬇︎この箇所)

InstrumentsのApp Launchの計測結果

System Interface Initializationでは何をしているのか

  • この項の内容は上記ブログに書いてあります。すでに読んで下さってる方は飛ばしていただければと思います。

処理は大きく"dyld"と"libSystemInit init"があります。
"libSystemInit init"ではアプリケーション内の低レベルのシステムコンポーネントの初期化をしているため、エンジニアは特別気にする必要はありません。
エンジニアが気にすべきところは"dyld"の内容になります。

"dyld"ではリソースの解析や共有ライブラリやフレームワークのロードを行っています。
つまりこの箇所にかかっている時間を削減したい場合、不要な実装を削除すること・dynamic libraryからstatic libraryへ変更することが非常に有効です。NewsPicksでもその2つを実施しました。

まずは結果から

成果は一目瞭然でSystem Interface Initializationの箇所の大幅削減に成功しました。
1秒は切れるかな?と思っていたのですが、予想以上の成果がありました。

左: 対応前 / 右: 対応後

具体的な作業内容

ではここからは実際に行った作業を紹介していきます。

不要な実装の削除

サービスがリリースされてから年月が経っているアプリだと、ABテストの残骸や仕様変更の残骸など参照されていない不要な実装が結構存在すると思います。調べてみたらNewsPicksにもかなり存在していました。
不要な実装の洗い出しは検索するといくつかツールが出てきますが、今回私はPeripheryを使用しました。

Peripheryの使用方法は本当に簡単で、CocoaPodsでインストールしコマンドperiphery scan --setupを実行するだけです。

しかし、ここからが大変です。吐き出された一覧を全て消していけたらまだ楽なんですが、たまに消してはいけない実装が参照されてない実装として出力されています。そのためひとつずつ確認して、丁寧に消していく必要がありました。
そのため約3000箇所も吐き出された一覧をひとつずつ丁寧に消していくこととなりました。本当に本当に大変でしたが、その分効果は期待できるので皆さんもぜひ負けずに取り組んで欲しいです。

dynamic libraryからstatic libraryへ変更

NewsPicksではライブラリの管理はCocoaPodsとSwift Package Manager(以下 SwiftPM)を使用していました。ライブラリの数も本当に多く、CocoaPodsで30個ほどSwiftPMで25個ほど使用しています。

使っていないライブラリを削除する

以前使っていたが使われなくなっていたライブラリの削除や、すごく簡単な部分に使われていてライブラリを使う必要のない箇所を自前実装して削除しました。
また、同じような機能を提供しているライブラリを複数使っていたので、どちらかに寄せることで不要になった方を削除しました。

例えば、SDWebImageKingfisherの両方が入っていたのを、Kingfisherに寄せることでSDWebImageを削除できました。

可能な限りCocoaPodsからSwiftPMへ移行する

CocoaPodsのままでもstatic libraryとして扱えますが、やはり将来性の面とApple純正でメンテナンスが楽な点などいろんな側面から、NewsPicksではSwiftPMをメインで使用していく方針にしています。
SwiftPMは基本的にstatic libraryとして扱っているため、大体移行するだけでそちらの目的も達成できます。

今回SwiftPMに対応しているものを全て移行する予定でしたが、なんと一番重いであろうFirebaseの移行はできませんでした。というのも、他で使っているライブラリが影響してしまっているのか理由は定かでないんですが、同じバージョンでもSwiftPMに移行しただけでエラーになりビルドが通らなくなりました。

Firebaseの問題は将来的には解決したい課題としてまだ残っています。

まとめ

Firebase Performance

今回はSystem Interface Initializationの改善の内容と結果についてお話ししました。
これだけでもFirebase Performanceで計測されているアプリの起動時間は平均1秒ほど改善されました!これは本当に思った以上の成果で嬉しい限りです。

現在違う箇所も対応を進めているので、またそれもブログにできたらいいなと思っています。
ぜひみなさんの会社でも、まだ起動時間の改善に取り組んでいなければチャレンジして結果を聞かせてください。

Page top