🙌

ネイティブアプリのパフォーマンスメトリクスについて考えた

2020/09/25に公開

動機

Web アプリケーションのパフォーマンスメトリクスについては、個人的にはあらゆる議論がされており、すでに一定の答えが出ている印象があった。

例えば、技術評論社から出版されている超速! Webページ速度改善ガイドでは、あらゆるベストプラクティスが網羅されているし、最近だと Google がサイトの健全性を示す指標として Core Web Vitals を発表した

Core Web Vitals は以下の 3 つの要素が土台となるもので、おそらく Google が膨大なデータからこれらが UX に大きく寄与すると導き出したものなのだろう。

  • Largest Contentful Paint は、ユーザーがページで最も有意義なコンテンツをどのくらい早く見ることができるかを表します。感覚的な読み込みスピードを測定し、ページ読み込みタイムラインにおいてページの主要コンテンツが読み込まれたと思われるタイミングを指します。
  • First Input Delay は、最初の入力までの遅延を表します。応答性を測定して、ユーザーが最初にページを操作しようとする場合に感じるエクスペリエンスを定量化します。
  • Cumulative Layout Shift は、ページがどのくらい安定しているように感じられるかを表します。視覚的な安定性を測定し、表示されるページ コンテンツにおける予期しないレイアウトのずれの量を定量化します。

Web の果たす役割として検索エンジン経由での集客というのは非常に大きいため、必然的にこのような指標を満たすように Web サイトを構築するようになるだろう。

しかし、ネイティブアプリ(iOS アプリや Android アプリ)についてはそれ単体での使いやすさの議論はよく見かけるが、特に他アプリと横並びで、パフォーマンス指標の比較についてはあまり議論している光景や資料を目にする機会が少ない印象があった。

そういった状況のなか、ネイティブアプリのパフォーマンス改善を定量的に行っていくために必要な指標とは何なのだろうと考えた。

Etsy の事例

いろいろと探していると、Etsy の 元 VP of Engineering の Lara Hogan が書いた gist が見つかった。

これは Etsy のネイティブアプリの計測についてのドラフトで、初稿は 2015 年とかなり前である。
しかし、コメント欄も含めて非常に参考になるので、今回はこれを紹介したい。
(Lara Hogan には掲載の許可を得ています! Thanks to @larahogan)

ちなみに Etsy とは手芸や古物などハンドメイドの商品を扱うアメリカの EC の会社。もともとは Web のみの展開だったが、のちに iOS アプリ、Android アプリがローンチされた。

アプリ全体のメトリクス

  • アプリの起動時間 - アイコンをタップしてからアプリを操作できるようになるまでにどれくらいの時間がかかるか?
  • クリティカルフローを完了するまでの時間 - 自動テストを使用して、ユーザーがチェックアウトフローを完了するまでにかかる時間など。
  • 無線使用量や GPS 使用量を含むバッテリー使用量
  • ピーク時のメモリ割り当て

画面ごとのメトリクス

  • フレームレート - どこでフレームを落としているのかを把握する必要があります(そして、ジャンクのスクロールを導入しています)。レンダリング時間、実行時間、描画時間を掘り下げることができるはずです。
  • メモリリーク - 自動テストを使用して、メモリリークを引き起こすフローやアクションを見つけることができますか?
  • Speed Index のアプリ版 - 時間をかけて上に折りたたまれた画面を目に見える形で完了させることができます。
  • リモート画像が画面に表示されるまでの時間
  • リンクをタップしてから次の画面で何かができるまでの時間
  • スピナーを見る平均時間

その他の考慮事項

  • API のパフォーマンス
  • ウェブビューのパフォーマンス

このなかでも「クリティカルフローを完了するまでの時間」を計測するというのは面白い試みだと思った。
たとえば、Starbucks のアプリのユースケースを考えてみると、レジで Pay の画面を開きバーコードを提示する必要があるので、このフローをクリティカルフローと呼ぶのがふさわしそうに思う。

仮にレジ前で Pay の画面を開くまでに 1 分かかっていたら店舗の業務にも影響を及ぼすだろう。

Launch Home Pay
image image image

Apple によるパフォーマンス改善の記事

Apple の MetricKit の Documentation 配下に Improving Your App's Performance という記事を見つけた。

以下のようなサイクルを回してパフォーマンス改善を行っていきましょうという主旨のものであるが、そのなかで具体的な指標について言及があった。

image

  • Decreasing app launch time improves the user experience, and reduces the chances of the iOS watchdog timer terminating the app.
  • Decreasing overall memory use reduces the likelihood of iOS freeing your app’s memory in the background, and improves responsiveness when a user switches back to your app.
  • Reducing disk writes speeds up your app’s overall performance, makes it more responsive, and reduces wear on users’ device storage.
  • Decreasing hang rate and hang duration improves your users’ perception of your app’s performance and responsiveness.
  • Reducing battery consumption and the use of power-hungry device features makes your app more reliable and helps ensure that the rest of the user's device is available when needed.

こちらを翻訳した結果が下記。

  • アプリの起動時間を短縮すると、ユーザーエクスペリエンスが向上し、iOS ウォッチドッグタイマーがアプリを終了させる可能性が低くなります。
  • 全体的なメモリ使用量を減らすことで、iOS がバックグラウンドでアプリのメモリを解放する可能性が減り、ユーザーがアプリに戻ったときの応答性が向上します。
  • ディスクの書き込みを減らすと、アプリの全体的なパフォーマンスが高速化され、応答性が向上し、ユーザーのデバイスストレージの消耗が軽減されます。
  • ハングレートとハング時間を減らすと、アプリのパフォーマンスと応答性に対するユーザーの認識が向上します。
  • バッテリー消費量を減らし、電力を消費するデバイス機能を使用することで、アプリの信頼性を高め、ユーザーのデバイスの残りの部分を必要なときに利用できるようにします。

Android Vitals

Android では Android Vitals という名前がついており、明確な定義がされている。

image

上記は実際の Play Console 上で確認できる Android Vitals のダッシュボードだが、ここに表示されている主な指標としてのそれぞれの定義は以下。

  • ANR 発生率
    • ANR が 1 回以上発生した 1 日のセッションの割合(%)です。1 日のセッションとは、1 日の間にアプリの利用があった日を指します。
  • クラッシュ発生率
    • クラッシュが 1 回以上発生した 1 日のセッションの割合(%)です。1 日のセッションとは、1 日の間にアプリの利用があった日を指します。
  • 停止した部分的な wake lock(バックグラウンド)
    • バックグラウンドで実行中にアプリで 1 時間以上続く部分的な wake lock が 1 回以上発生したセッションの割合(%)です。一部のアプリでは、音楽のストリーミングなどの主要機能を実現するには長い wake lock が必要になります。このデータは、デバイスが充電中でないときにのみ収集されます。
  • 過剰なウェイクアップ
    • アプリで平均して 1 時間に 10 回を超える wakeup が発生したセッションの割合(%)です。このデータは、デバイスが充電中でないときにのみ収集されます。

すべての指標としては、下記が定義されている。(上記も項目内に含む)

  • 電池
    • 過剰なウェイクアップ
    • 停止した部分的な wake lock
    • 停止した部分的な wake lock(バックグラウンド)
    • バックグラウンドでの過度の Wi-Fi スキャン
    • バックグラウンドでの過度のネットワーク使用量
  • 安定性
    • ANR 発生率
    • 複数回 ANR 発生率
    • クラッシュ発生率
    • 複数回クラッシュ発生率
  • アプリの起動時間
    • コールド スタートアップ時間が長い
    • ウォーム スタートアップ時間が長い
    • ホット スタートアップ時間が長い
  • レンダリング
    • 過度に遅いフレーム
    • 過度にフリーズしたフレーム
  • 権限
    • 権限の拒否

さらにこちらの動画は Google I/O 2018 にて Android Vitals についての発表があったときのものだが、パフォーマンス改善がどれだけビジネスに良い影響を与えるかという内容からはじまり、具体的な実装について踏み込むなど詳細まで解説しているので一度見てみたほうが良い。

Android vitals: debug app performance and reap rewards (Google I/O '18)

総括

iOS アプリ、Android アプリ、どちらにも当てはまるパフォーマンス指標としては大項目として以下を抑えておくと間違いない。

  • アプリの起動時間
  • メモリの使用量
  • ディスクへの書き込み
  • ハング率とハング時間
  • バッテリー消費

Android Vitals はこれらをブレイクダウンした具体的な指標を定義してくれているので、適用できる(観測可能な)ものを iOS アプリの指標として選び、継続的に観測、改善まで行えると良いと思う。

感想

冒頭触れた Core Web Vitals という指標については知っていたが、すでに 2 年前に Android Vitals という指標が発表されていたことは知らなかったので、良い勉強になった。


この記事は GitHub 連携で書いています。加筆修正など修正 PR を受け付けています!
https://github.com/serima/zenn-content

Discussion