Firebase Performance Monitoringの基本の概念と実装について整理した

Firebase Performance Monitoringの基本の概念と実装について整理した

Table of Contents

アプリを使用するユーザーの利用環境を明確に把握したニーズが強くなったので、前々から気になっていたFirebase Performance Monitoringについて調べることにしました。
なお本記事はiOSを重点に調査しています。

Firebase Performance Monitoringとは?

iOS,Android,Webアプリのパフォーマンス特性を知ることが出来ます。
SDKをアプリに統合するだけで、プロファイルコード不要で各パフォーマンスデータを収集し、Firebaseコンソールから分析できます。

これによりアプリのパフォーマンス問題を解決できます。

なお Performance Monitoringが自動収集するデータには名前、メアド、電話番号などの個人情報は一切収集しません。
またカスタム属性で個人を特定できる情報は使用しないでください。

公式

主な機能

おもに3つの機能があります。

パフォーマンスデータとして次の項目を自動収集

  • アプリ起動時間
  • HTTP/Sネットワーク上のリクエスト
  • 画面ごとのレンダリングデータ
  • フォアグラウンドでのアクティビティ
  • バックグラウンドでのアクティビティ

パフォーマンス課題を見つけやすくする

パフォーマンス指標として次の項目を確認できます。

  • デバイス
  • アプリのバージョン
  • OS

アプリ毎にPerformance Monitoringをカスタマイズ

自作や新しい画面やUIの表示などのパパフォーマンストレーサーを作成できます。
またカスタム指標を用意し、トレース時に定義したイベント(キャッシュヒットなど)をカウントできます。

例えばアプリ独自にインメモリのキャッシュ機構を構築してる場合のキャッシュヒット率を収集することができます。

トレースとは?

トレースとは2つの時点の間で取得されたパフォーマンスデータのレポートです。

Performance Monitoringの仕組み

大きくレポートタイミングとして、トレースと通信キャプチャに分かれており、その配下に指標があります。

トレースには2種類ある

トレースには自動トレースとカスタムトレースの2種類のトレースがあります。

自動トレース

iOSやAndroidアプリで自動で組み込まれるデフォルトトレースです。

  • アプリ起動トレース
    • ユーザーがアプリを起動してから、アプリが応答するまでの時間を測定
    • コンソールでは _app_start 報告指標は期間
    • 開始タイミングは、アプリが最初のObjectをロードすると開始します
    • 終了タイミングは、 UIApplicationDidBecomeActiveNotification通知受信後の最初の正常な実行ループ後に停止します。
  • フォアグラウンドアプリのトレース
    • アプリがフォアグラウンドで実行されていてユーザーが利用できる時間を測定
    • コンソールでは _app_in_foreground 報告指標は期間
    • 開始タイミングは、UIApplicationDidBecomeActiveNotificationを受け取ると開始
    • 終了タイミングは、UIApplicationWillResignActiveNotificationを受け取ると停止
  • バックグラウンドアプリのトレース
    • アプリがバックグラウンドで実行されている時間を測定
    • コンソールでは _app_in_background 報告指標は期間
    • 開始タイミングは、アプリがUIApplicationWillResignActiveNotificationを受け取ると開始
    • 終了タイミングは、UIApplicationDidBecomeActiveNotificationを受け取ると停止
  • 画面トレース
    • 画面の存続期間を通じて低速なフレームとフリーズしたフレームを測定
    • 指標はレンダリングが遅いフレームとフリーズしたフレームのみ報告されます。
    • コンソールでは他トレースとは別テーブルに表示されます。
    • 開始タイミングは、 viewDidAppear:を呼び出すと keyWindow内のすべてのUIViewControllerについて開始
    • 終了タイミングは、viewDidDisappear:を呼び出すと停止
    • 正規のコンテナビューコントローラはキャプチャされません。(UINavigationViewControllerなど)

自動トレース情報

Firebase Performance Monitoringでは次の種類の情報がデフォルトで収集します。URL

  • 機種、OS、画面の向きなどの全般的な端末情報
  • RAM とディスクのサイズ
  • CPU 使用率
  • 携帯通信会社(モバイルの国コードとネットワーク コードに基づく)
  • 無線通信 / ネットワークの情報(例: Wi-Fi、LTE、3G)
  • 国(IP アドレスに基づく)
  • ロケール / 言語
  • デバイスのジェイルブレイクまたはルート権限取得
  • 電池残量と充電状態
  • アプリのバージョン
  • アプリの状態(フォアグラウンドまたはバックグラウンド)
  • アプリのパッケージ名
  • 仮名のアプリ インスタンス識別子
  • ネットワークの URL(URL パラメータやペイロードのコンテンツを含まない)と以下の対応する情報:
    • 応答コード(例: 403、200)
    • ペイロードのサイズ(バイト単位)
    • 応答時間
  • 自動トレースの継続時間

カスタムトレース

ユーザー独自のトレースです。SDKに用意されたAPIを使ってカスタムトレースの開始と終了を定義することできます。

またカスタムトレースを詳細に構成することで、該当する範囲内で発生したパフォーマンス関連イベントのカスタム指標の記録もできます。

これは前述したメモリキャッシュ機構でいう、キャッシュヒット数とミス数といった指標や、
UIが一定期間反応しなかった回数などカスタム指標を作成できます。

HTTP/Sネットワークリクエスト

アプリがリクエストを発行してレスポンスが返ってくるまでの時間をキャプチャするレポートです。
次の指標を収集します。

  • 応答時間
    • リクエスト発行からレスポンスの完全受信までの時間
  • ペイロードサイズ
    • ダウンロード/アップロードされたネットワークペイロードのバイトサイズ
  • 成功率
    • 全レスポンスに対する成功レスポンスの割合. これは通信障害やサーバー障害を測定することを目的としてる

属性

パフォーマンスデータはトレースとHTTP/Sネットワークリクエストの両レポートで次のように分類されています。(以下はiOS/Android)

  • トレース
    • アプリバージョン
    • OS レベル
    • デバイス
    • 無線通信
    • 携帯通信会社
  • HTTP/Sネットワークリクエスト
    • アプリバージョン
    • OS レベル
    • デバイス
    • 無線通信
    • 携帯通信会社
    • MIMEタイプ

またカスタム属性を設定することもできます。

これらは、コンソール上でパフォーマンスデータを属性でフィルタリング(セグメント化)することで、さまざまなシナリオにフォーカスした指標を得ることが出来ます。

組み込んでみる

  1. Performance Monitoringをアプリに追加
  2. Firebaseコンソールで結果を確認する

この2工程です。 なお Firebaseの追加自体はこちらの公式サイトを参照してください。

Performance Monitoringをアプリに追加

Podfile

pod 'Firebase/Analytics'
pod 'Firebase/Performance'

後は $ pod install するだけです。

UIApplicationDelegateapplication:didFinishLaunchingWithOptions:FirebaseApp.configure() を追加する必要がありますが、
すでにFirebaseを使っている場合はこのコードは既に組み込まれているかと思います。

これで 自動トレースHTTP/Sネットワークリクエストを監視するようになります。

※ なお Firebase/Performance を追加すると依存関係として Remote Config が組み込まれます。

もし pod install で UUID重複警告が出た場合は、Firebase関連podを最新にupdateすることで回避できました。

Firebaseコンソールへの反映には12時間以内と記載ありますが、私の環境では12時間近くかかりました。

Firebaseコンソールで結果を確認する

Firebase コンソール で結果が反映されることを確認します。結果は通常12時間以内で表示されます。

カスタムトレースとカスタム指標の実装

1つのトレースに複数の指標を追加できます。

カスタムトレースはIDが文字列になっており、いくつか制限があります。

  • 先頭と末尾が空白ではないこと
  • 先頭がアンダースコア_でないこと
  • 32文字以下であること

カスタムトレースを追加する

import FirebasePerformance

let trace = Performance.startTrace(name: "Hoge")
// トレースしたいコードを挟む
trace.stop()

カスタム指標を追加する

次のコードのようにトレースの間にカスタム指標コードを追加します。

let trace = Performance.startTrace(name: "Hoge")
trace.incrementMetric(named: "cache-miss-count", by: 1)
// トレースしたいコードを挟む
trace.stop()

HTTP/Sネットワークリクエストのモニタリング追加

基本的に自動収集されますが、一部収集されないケースがあります。 その場合はカスタムネットワークリクエストを次のように追加します。

guard let metric = HTTPMetric(url: "https://your.domain.com", httpMethod: .get) else { return }
metric.start()

let hogeRequest = HogeRequest()
HogeAPI.get(request: hogeRequest, completion: {
  metric.stop()
})

リクエストの発行前とレスポンスの受信完了直後に start()stop() を呼んでください。

カスタム属性の追加

Performance Monitoringでは属性を使用することでパフォーマンスデータをセグメント化し、シナリオ別にパフォーマンスを絞り込むことができます。

カスタム属性はトレースごとに設定出来ます。
またカスタム属性にはいくつか制限があります。

  • カスタム属性の数は、1トレース最大5個に制限
  • 名前は、先頭と末尾に空白がない
  • 先頭にアンダースコア_がない
  • 32文字以下

にする必要があります。

var trace = Performance.sharedInstance().trace(name: "Hoge")
trace.setValue("Male", forAttribute: "Gender")

// 更新も可能
trace.setValue("Female", forAttribute: "Gender")

// 削除
trace.removeAttribute("Gender")

// 属性読み込み
let gender: String? = trace.valueForAttribute("Gender")

// トレースに紐づく全属性読み込み
let attributes: [String: String] = trace.attributes

注意事項

公式ではいくつか注意事項があります。

  • GTMSQLiteを使ってる場合は、互換性がないため、Performance Monitoringを使用しないほうがいいです。
  • FirebaseApp.configure()の呼び出し後のメソッド入れ替えは影響する可能性があります。
  • iOS8.0~8.2シミュレータでは正常に動作する保証がありません
  • NSURLSessionのbackgroundSessionConfigurationは接続時間が予想より長くなります。

Firebase Performance Monitoring を無効にする方法は3つある

大きく分けてInfo.plistを設定する方法とコード上で設定する方法に分かれます。

またコード上での設定では自動とカスタムそれぞれの制御ができます。

Info.plist を設定する方法

  • ビルド時に無効にしておき、ランタイムで有効/無効を制御できる方法(通常無効
  • ビルド時に完全無効にしておき、ランタイムで有効に変更できない方法(完全無効

通常無効

Info.plistfirebase_performance_collection_enabledfalse にすることで、無効にできます。

完全無効

Info.plistfirebase_performance_collection_deactivatedtrue にすることで、完全無効にできます。

これは 通常無効(firebase_performance_collection_enabled) の設定をオーバーライドします。

前者はつまりコード上で制御できて、後者は制御が不可能になります。

コード上で設定する方法

Performance.sharedInstance().isInstrumentationEnabled で自動トレースとHTTP/Sネットワークリクエストを有効/無効制御できます。

Performance.sharedInstance().isDataCollectionEnabled でカスタムトレースを有効/無効制御できます。

コード上の変更では前述した完全無効では効果ありません。

デバッグ版は無効にする

開発中ではパフォーマンス測定しないために無効にしておき、本番ではコード上で有効にする例があります。

デバッグ情報が入った開発版では本来の測定より重いレポートとなるため、あまりパフォーマンス測定の効果は得られません。

本番のみ有効にするという利用ケースもあります。

Remote Config と組み合わせて無効制御する

コード上で無効制御ができることとRemote Configを組み合わせることで、デプロイ済みのアプリに対して無効/有効設定ができるようになります。

詳しくは公式の記事を確認ください。

このエントリーをはてなブックマークに追加