見出し画像

iOSアプリのパフォーマンス計測に入門してみた

はじめに

NTTレゾナントテクノロジーの冨田です。モバイルアプリ開発を担当しています。

皆さんは開発に携わっているアプリのパフォーマンスについて把握していますか?また、どのように計測していますか?
パフォーマンスの重要性については今更言うまでもありませんが、ついつい機能追加や改善を優先してしまいパフォーマンスについては後回しにしがちです。
かくいう私も正直なところパフォーマンスについて腰を据えて取り組んだことがなく、改善するにあたっての指標やそもそもどのような手法があるのか分からない状態でした。
そこで今回は、Appleが提供しているパフォーマンス計測手法であるXcode Metrics Organizer、MetricKitについて調べた基礎知識を紹介したいと思います。

なお、前提知識としてApple公式ドキュメントの「Improving Your App's Performance」を一読しておくことをオススメします。

以下の解説記事もありますので参考にしてみてください。

Xcode Metrics Organizer

Xcode11以降であればデフォルトで利用可能で、匿名化された市場ユーザー環境のパフォーマンスデータを「Organizer > Metrics」にて確認することができます。アプリ側での特別な設定や実装は不要です。

データはバージョン毎に集計され、直近16バージョン分のデータが保持されます。比較対象のバージョンを選択することで最新バージョンとの比較が可能です。(最新バージョンとの比較機能なので過去バージョン同士の比較は不可能です。)
また、フィルタ機能も用意されており、「端末」や「パーセンタイル」でのフィルタリングが可能です。

Xcode14にて用意されているメトリクスは下記7種になります。

なお、これらのデータは毎日更新されます。画面下部に最終更新日時が表示されているのでそちらで更新されたタイミングを確認可能です。

1. 集計対象

下記の条件を満たしているユーザーのパフォーマンスデータのみが集計対象となります。

  • iOS 12.3以降であること

  • AppStoreを通じて配布されたアプリであること(開発版、TestFlight版は対象外)

  • 「プライバシーとセキュリティ」>「解析と改善」> 「デベロッパと共有」がONであること

2. メトリクスが表示されないアプリ

閾値が公開されていないため正確な数値は分かりませんが、一定数以上のパフォーマンスデータが集計されないとメトリクスが表示されないので注意が必要です。
データ不足である場合は下記のような表示となります。

3. 各種メトリクスについて

3-a. Battery Usage

1日の中でデバイスが電源に接続されていない状態でアプリを動作させた際のバッテリー使用量を表しています。
アプリの状態別に計測されており、上のグラフはフォアグラウンド状態、下のグラフはバックグラウンド状態でのバッテリー使用量をそれぞれ確認できます。

グラフ上の色分けはバッテリーを使用したカテゴリを表しており、それぞれのパーセンテージも確認することができます。
カテゴリの詳細に関しては公式ドキュメントを参照してください。(オーディオ、ネットワーク など)
過去バージョンと比較して極端にバッテリー使用量が増えている場合は注意が必要です。また、アプリのユースケースと紐づかないカテゴリでバッテリーが消費されている場合も注意が必要です。

3-b. Disk Writes

1日の中でアプリがSSDに書き込んだデータ量がMB単位で表示されます。

ディスクへの書き込み操作と読み込み操作では書き込み操作の方が遅く、書き込み操作が完了するまで新しい読み込み操作はキューイングされます。キューイングされた読み込み操作の要求元のスレッドはブロックされてしまうので、ディスクへの書き込みが過剰に行われるとその分アプリの応答性が悪くなってしまいます。
過去バージョンと比較して予想外のデータ書き込み量の増加を検知した場合は、データの書き込み頻度が多すぎる可能性があるため注意が必要です。

3-c. Hang Rate

ハングとは、ユーザーが何かしらの操作をした後にViewの更新が止まってしまい操作が効かなくなることを指します。例えば、ボタンをタップしても反応しないなどが挙げられます。
このメトリクスはアプリがユーザーの操作に対して応答しなかった1時間辺りの秒数(ハング率)を表しており、無応答の時間が250msを超えた場合のみハングが発生したとして集計されています。

過去バージョンと比較してハング率が悪化している場合はUXに影響があるため見直しが必要です。追加・改修した機能でメインスレッドのブロックが発生している可能性があります。
ちなみにAppleはハングの閾値を100msとしており、これより短い秒数であればほとんど目立たない遅延だとしています。

余談ですが、ハングを調査する方法としてiOS16以上であればデベロッパーモードに「Hang Detection」のメニューが追加されています。Instrument等を利用せずとも手軽に調査できるのでオススメです。

3-d. Launch Time

ユーザーがアプリアイコンをタップしてから最初の画面が描画されるまでの時間がミリ秒単位で表示されます。

過去バージョンと比較してアプリの起動時間が延びている場合はUXに影響があるため見直しが必要です。
ちなみにアプリの起動には3種類あり、ここで注視すべきなのはCold LaunchとWarm Launchです。

・Cold Launch:インストール後の初回起動、端末の再起動後や長期間使用していない状態でアプリを起動した場合に発生する。ディスクからメモリに取り込み、サービスの起動とプロセスの生成をするため時間がかかる。次回以降はWarm Launchになる。

・Warm Launch:すでにアプリをメモリに取り込み、システム側のサービスをいくつか立ち上げている状態でアプリを起動した場合に発生する。少し速く、少し安定した起動が可能になる。

・Resume:ユーザーがホーム画面やAppスイッチャーからアプリに再びアクセスしたときに発生する。アプリはすでに起動しているので高速に動作する。

https://developer.apple.com/videos/play/wwdc2019/423

「ユーザーがアプリアイコンをタップしてから最初のフレームが描画されるまで400ミリ秒以内」というのが起動時間に関してAppleが提示している指標となります。

3-e. Memory

iOSはアプリのメモリ使用量を1日を通して定期的にサンプリングしています。上のグラフは取得したサンプルのいずれかで観察された最高のメモリ使用量がMB単位で表示されています。下のグラフはバックグラウンド状態でのメモリ使用量が表示されています。

過去バージョンと比較してメモリ使用量が異常に増えている場合は注意が必要です。下記ドキュメントに一般的な対処方針がまとめられているので併せて確認することをオススメします。

3-f. Scrolling

スクロールヒッチとは、ユーザーがスクロール操作をした際になめらかなアニメーションにならず飛び飛びになってしまう現象のことを指します。
ヒッチした時間/スクロールした時間で算出されたヒッチ率がグラフで表示されています。

Appleはヒッチ率におけるユーザの体感(閾値)を下記のとおりとしています。

  • 5.0ms/s以下 (ヒッチが1秒あたり5ミリ秒以下)スムーズ

  • 5.0ms/s-10.0ms/s (ヒッチが1秒あたり5から10ミリ秒の間)引っかかる

  • 10.0ms/s以上 (ヒッチが1秒あたり10ミリ秒以上)遅い

過去バージョンと比較してヒッチ率が悪化している場合はUXに影響があるため見直しが必要です。

3-g. Terminations

1日の中でアプリケーションが異常終了した回数の平均値を表しています。上段はフォアグラウンド状態、下段はバックグラウンド状態での異常終了です。

過去バージョンと比較して平均値が増加している場合は注意が必要です。公式ドキュメントに異常終了する理由がまとめられているので併せて確認することをオススメします。

クラッシュであればFirebase Crashlyticsなどで収集可能なメトリクスデータも活用すると良いでしょう。

4. Xcode Organizer Insights

Xcode13以降であればデフォルトで利用可能で、Organizer > Insightsにて確認することができます。直近4バージョンと比較して注視するべきパフォーマンスの劣化を自動で検知する機能です。
検知対象となる閾値は公開されておらず変更することもできないので、検知された内容に関しては本当に対策するべきか精査が必要です。

5. App Store Connect APIを利用してメトリクスを取得する

各メトリクスとXcode Organizer InsightsのデータはApp Store Connect APIを利用して取得することができます。
iOSDC Japan 2022の下記トークにて活用事例が紹介されていますので興味があれば確認してみてください。
App Store Connect APIにて取得したメトリクスデータをBigQueryにまとめてGoogle Data Portalで表示するといった事例が紹介されています。


また、前述した「Metricsが表示されないアプリ」を対象にした場合は、APIリファレンスに下記の記載があるためApp Store Connect APIを用いてもデータは取得できないと思われます。こちらに関しては未検証であるため検証ができ次第、結果を追記します。

Allow a few days after releasing your app for Apple to collect and organize logs into reports. The system behind the API requires significant usage of your app before it makes metrics available, and each metric has different usage thresholds.

https://developer.apple.com/documentation/appstoreconnectapi/power_and_performance_metrics_and_logs/retrieve_power_and_performance_metrics_and_log_insights#overview

MetricKit

iOS13以降で使用可能なアプリのパフォーマンスに関するデータを収集するフレームワークです。これを使用することで市場ユーザー環境のパフォーマンスデータを詳細に把握することができます。

詳細な導入手順・実装については割愛しますが、基本的には下記のサンプルコードが流用可能です。

didReceiveメソッドにてレポート(MXMetricPayload or MXDiagnosticPayload)が取得可能で、最大1日1回、過去24時間分のデータを含むレポートをシステムから受信します。
このレポートを蓄積する仕組みは提供されていないため、自社サーバやデータ収集サービスに送信する仕組み作りが必要です。この辺りのシステム構成は事前に検討した上で用意しておく必要があります。

MXMetricPayloadとMXDiagnosticPayload から得られる情報は以下です。

1. MXMetricPayload

端末の基本情報、アプリのパフォーマンスなどを解析するためのデータが取得可能です。

  • バッテリー

    • CPU, GPU情報

    • ディスプレイ情報

    • ネットワーク情報

    • 位置情報

  • パフォーマンス

    • メモリ使用量

    • アプリの起動と再開

    • ハングが起こった時間

    • ヒッチ率(iOS14以上)

    • 異常終了した理由と発生回数(iOS14以上)

  • ストレージ

    • ディスク書き込みデータ量

2. MXDiagnosticPayload

iOS14以降から利用可能で、クラッシュやアプリの診断情報が取得可能です。

  • パフォーマンス

    • クラッシュレポート

    • CPU例外レポート

  • 応答性

    • アプリの合計起動時間(iOS16以上)

    • アプリの合計ハング時間

  • ストレージ

    • ディスク書き込み例外レポート

※それぞれにcallStackTreeが含まれる

最後に

今回はXcode Metrics Organizer、MetricKitの基礎知識について紹介しました。
基本的には公式ドキュメントに記載されている内容の検証をした感じですが、存在を初めて知った!などこの記事がみなさんにとって少しでも参考になれば幸いです。
改善サイクルを回していくための道のりはまだまだ険しいですが、引き続き勉強していきたいと思っています。

宣伝

NTTレゾナントテクノロジーでは一緒に働いてくれるAndroid/iOSアプリエンジニアを募集中です。もし興味がありましたら採用ページを是非ご覧ください。

参考リンク

本文中に記載しているものは除いています。

iOSアプリのパフォーマンス計測をおさらいする
https://speakerdeck.com/kariad/iosapurifalsepahuomansuwoosaraisuru

iOSアプリのスクロールヒッチとハングに関して
https://jmty-tech.hatenablog.com/entry/2022/11/18/183259

MetricKit 入門
https://qiita.com/ahiru___/items/14e443435eb1a59d615b

iOS13で新しく追加されたMetricKitがとてもすごい件
https://qiita.com/ahiru___/items/d794caae35ecfb4a1dfb

iOS 14 でのMetricKitの新機能について / New function of MetricKit on iOS 14
https://speakerdeck.com/sansanbuildersbox/new-function-of-metrickit-on-ios-14

MetricKit をFirebaseやXcode Organizerのmetricsと比較してみた話
https://lab.mo-t.com/blog/metrickit

Xcodeでアプリのディスク書き込み量をモニタリングする方法
https://zenn.dev/numatech/articles/c4c86fc14e5d52


この記事が気に入ったらサポートをしてみませんか?