1。概要
このコードラボでは、機能のロールアウト中にアプリのパフォーマンスを監視する方法を学習します。サンプル アプリには基本的な機能があり、Firebase Remote Config フラグに基づいて異なる背景画像を表示するように設定されています。アプリのパフォーマンスを監視するためのトレースの計測、アプリへの構成変更のロールアウト、効果の監視、およびパフォーマンスを向上させる方法を確認します。
学べること
- Firebase Performance Monitoring をモバイル アプリに追加して、すぐに使える指標(アプリの起動時間、遅いフレームやフリーズしたフレームなど)を取得する方法
- カスタム トレースを追加してユーザー ジャーニーの重要なコード パスを理解する方法
- パフォーマンス監視ダッシュボードを使用してメトリクスを理解し、機能のロールアウトなどの重要な変更を追跡する方法
- 主要な指標を監視するためにパフォーマンス アラートを設定する方法
- Firebase Remote Config の変更をロールアウトする方法
前提条件
- Android Studio 4.0以降
- API レベル 16 以降の Android エミュレータ。
- Java バージョン 8 以降
- Firebase Remote Configの基本的な理解
2. サンプルプロジェクトのセットアップ
コードをダウンロードする
次のコマンドを実行して、このコードラボのサンプル コードのクローンを作成します。これにより、マシン上にcodelab-perf-rc-android
というフォルダーが作成されます。
$ git clone https://github.com/FirebaseExtended/codelab-feature-rollout-performance.git
マシンに Git がない場合は、GitHub からコードを直接ダウンロードすることもできます。
firebase-perf-rc-android-start
フォルダー内のプロジェクトを Android Studio にインポートします。おそらく、いくつかの実行時例外が表示されるか、 google-services.json
ファイルの欠落に関する警告が表示されるでしょう。これは次のセクションで修正します。
このコードラボでは、 Firebase Assistantプラグインを使用して、Android アプリを Firebase プロジェクトに登録し、必要な Firebase 構成ファイル、プラグイン、依存関係を Android プロジェクトに追加します。すべて Android Studio 内から行います。
アプリを Firebase に接続する
- Android Studio /ヘルプ>アップデートの確認に移動して、最新バージョンの Android Studio と Firebase Assistant を使用していることを確認します。
- [ツール] > [Firebase]を選択して、 [アシスタント]ペインを開きます。
- アプリに追加するパフォーマンス監視を選択し、 [パフォーマンス監視を開始する]をクリックします。
- [Firebase に接続]をクリックして Android プロジェクトを Firebase に接続します(これにより、ブラウザで Firebase コンソールが開きます) 。
- Firebase コンソールで[プロジェクトの追加]をクリックし、Firebase プロジェクト名を入力します(すでに Firebase プロジェクトがある場合は、代わりにその既存のプロジェクトを選択できます) 。 [続行]をクリックして規約に同意し、Firebase プロジェクトと新しい Firebase アプリを作成します。
次に、新しい Firebase アプリを Android Studio プロジェクトに接続するためのダイアログが表示されます。
- 「接続」をクリックします。
- Android Studioを開きます。 [アシスタント]ペインに、アプリが Firebase に接続されていることの確認が表示されます。
アプリにパフォーマンス監視を追加する
Android Studio の[アシスタント]ペインで、 [アプリにパフォーマンス監視を追加]をクリックします。
変更を受け入れるためのダイアログが表示されます。その後、Android Studio はアプリを同期して、必要な依存関係がすべて追加されていることを確認します。
最後に、Android Studio の[アシスタント]ペインに、すべての依存関係が正しく設定されたことを示す成功メッセージが表示されます。
追加の手順として、「(オプション)デバッグ ログを有効にする」の手順に従ってデバッグ ログを有効にします。同じ手順が公開ドキュメントにも記載されています。
3. アプリを実行する
アプリのモジュール (アプリレベル) ディレクトリにgoogle-services.json
ファイルが表示され、アプリがコンパイルされるはずです。 Android Studio で、 [実行] > [「アプリ」を実行]をクリックして、Android エミュレータ上でアプリをビルドして実行します。
アプリを実行すると、最初に次のようなスプラッシュ画面が表示されます。
数秒後、デフォルトの画像を含むメイン ページが表示されます。
ボンネットの下で何が起こっているのでしょうか?
スプラッシュ スクリーンはSplashScreenActivityに実装されており、次のことを行います。
-
onCreate()
では、Firebase Remote Config 設定を初期化し、このコードラボの後半で Remote Config ダッシュボードに設定する設定値を取得します。 -
executeTasksBasedOnRC()
で、seasonal_image_url
フラグの構成値を読み取ります。 URL が構成値によって指定されている場合、イメージは同期的にダウンロードされます。 - ダウンロードが完了すると、アプリはMainActivityに移動し、
finish()
を呼び出してSplashScreenActivity
を終了します。
MainActivity
で、Remote Config を通じてseasonal_image_url
が定義されている場合、この機能が有効になり、ダウンロードされた画像がメイン ページの背景として表示されます。それ以外の場合は、デフォルトの画像 (上に表示) が表示されます。
4. リモート設定をセットアップする
アプリが実行されたので、新しい機能フラグを設定できます。
- Firebase コンソールの左側のパネルで[エンゲージ]セクションを見つけ、 [リモート設定]をクリックします。
- 「構成の作成」ボタンをクリックして構成フォームを開き、パラメータキーとして
seasonal_image_url
を追加します。 - [説明の追加]をクリックし、次の説明を入力します
Shows a seasonal image (replaces default) in the main page when the restaurant list is empty.
- [新規追加] -> [条件値] -> [新しい条件の作成]をクリックします。
- 条件名として
Seasonal image rollout
と入力します。 -
Applies if...
セクションで、User in random percentile <= 0%
を選択します。 (後のステップでロールアウトする準備ができるまで、この機能は無効のままにしておきます。) - [条件の作成]をクリックします。後でこの条件を使用して、新しい機能をユーザーにロールアウトします。
- [最初のパラメータの作成] フォームを開き、 [季節画像の値] ロールアウトフィールドを見つけます。季節の画像をダウンロードする URL を入力します:
https://images.unsplash.com/photo-1552691021-7043334e0b51
- デフォルト値を空の文字列のままにしておきます。これは、URL からダウンロードされた画像ではなく、コードベース内のデフォルトの画像が表示されることを意味します。
- 「保存」をクリックします。
新しい構成がドラフトとして作成されていることがわかります。
- [変更の公開]をクリックし、上部の変更を確認してアプリを更新します。
5. データ読み込み時間の監視を追加する
アプリはMainActivity
表示する前にいくつかのデータをプリロードし、スプラッシュ画面を表示してこのプロセスを非表示にします。ユーザーがこの画面で長時間待たされることは望ましくないため、通常はスプラッシュ画面が表示される時間を監視することが有益です。
Firebase Performance Monitoring はまさにそれを行う方法を提供します。カスタム コード トレースをインストルメント化して、データの読み込み時間や新機能の処理時間など、アプリ内の特定のコードのパフォーマンスを監視できます。
スプラッシュ スクリーンの表示時間を追跡するには、スプラッシュ スクリーンを実装するActivity
であるSplashScreenActivity
にカスタム コード トレースを追加します。
-
splash_screen_trace
という名前のカスタム コード トレースを初期化、作成、開始します。
SplashScreenActivity.java
// ...
import com.google.firebase.perf.FirebasePerformance;
import com.google.firebase.perf.metrics.Trace;
// ...
public class SplashScreenActivity extends AppCompatActivity {
private static final String TAG = "SplashScreenActivity";
private static final String SEASONAL_IMAGE_URL_RC_FLAG = "seasonal_image_url";
// TODO: Initialize splash_screen_trace
private final Trace splashScreenTrace = FirebasePerformance.startTrace("splash_screen_trace");
// ...
}
-
SplashScreenActivity
のonDestroy()
メソッドでトレースを終了します。
SplashScreenActivity.java
@Override
protected void onDestroy() {
super.onDestroy();
// TODO: Stop the splash_screen_trace here
splashScreenTrace.stop();
}
新しい機能は画像をダウンロードして処理するため、機能がSplashScreenActivity
に追加した時間を追跡する 2 番目のカスタム コード トレースを追加します。
-
splash_seasonal_image_processing
という名前のカスタム コード トレースを初期化、作成、開始します。
SplashScreenActivity.java
private void executeTasksBasedOnRC(FirebaseRemoteConfig rcConfig) {
String seasonalImageUrl = rcConfig.getString(SEASONAL_IMAGE_URL_RC_FLAG);
Log.d(TAG, SEASONAL_IMAGE_URL_RC_FLAG + ": " + seasonalImageUrl);
if (!seasonalImageUrl.isEmpty()) {
// TODO: Start the splash_seasonal_image_processing here
final Trace seasonalImageProcessingTrace = FirebasePerformance
.startTrace("splash_seasonal_image_processing");
// ...
}
}
-
RequestListener
のonLoadFailed()
メソッドとonResourceReady()
メソッドの両方でトレースを終了します。
SplashScreenActivity.java
Glide.with(SplashScreenActivity.this.getApplicationContext())
.asBitmap()
.load(seasonalImageUrl)
.signature(new ObjectKey(Utils.getCacheUUID()))
.listener(new RequestListener<Bitmap>() {
@Override
public boolean onLoadFailed(
@Nullable GlideException e,
Object model, Target<Bitmap> target,
boolean isFirstResource) {
// TODO: Stop the splash_seasonal_image_processing here
seasonalImageProcessingTrace.stop();
launchMainActivity();
return true;
}
@Override
public boolean onResourceReady(Bitmap resource, Object model,
Target<Bitmap> target, DataSource dataSource,
boolean isFirstResource) {
// TODO: Stop the splash_seasonal_image_processing here
seasonalImageProcessingTrace.stop();
launchMainActivity();
return true;
}
})
.preload();
スプラッシュ スクリーンの継続時間 ( splash_screen_trace)
と新機能の処理時間 ( splash_seasonal_image_processing
) を追跡するカスタム コード トレースを追加したので、Android Studio でアプリを再度実行します。 Logging trace metric: splash_screen_trace
とその後にトレースの継続時間が含まれるロギング メッセージが表示されます。新しい機能がまだ有効になっていないため、 splash_seasonal_image_processing
のログ メッセージは表示されません。
6. カスタム属性をトレースに追加します
カスタム コード トレースの場合、Performance Monitoring はデフォルトの属性(アプリのバージョン、国、デバイスなどの一般的なメタデータ)を自動的に記録するため、 Firebase コンソールでトレースのデータをフィルタリングできます。カスタム属性を追加して監視することもできます。
アプリでは、スプラッシュ画面の継続時間と新機能の処理時間を監視するための 2 つのカスタム コード トレースを追加しました。これらの期間に影響を与える可能性がある要因は、表示される画像がデフォルトの画像であるか、または画像を URL からダウンロードする必要があるかどうかです。そして、最終的には、画像をダウンロードするための異なる URL が作成される可能性があります。
そこで、季節画像の URL を表すカスタム属性をこれらのカスタム コード トレースに追加しましょう。こうすることで、後からこれらの値で期間データをフィルタリングできます。
-
executeTasksBasedOnRC
メソッドの先頭に、splash_screen_trace
のカスタム属性 (seasonal_image_url_attribute
) を追加します。
SplashScreenActivity.java
private void executeTasksBasedOnRC(FirebaseRemoteConfig rcConfig) {
String seasonalImageUrl = rcConfig.getString(SEASONAL_IMAGE_URL_RC_FLAG);
Log.d(TAG, SEASONAL_IMAGE_URL_RC_FLAG + ": " + seasonalImageUrl);
// TODO: Add a custom attribute "seasonal_image_url_attribute" to splash_screen_trace
if (seasonalImageUrl.isEmpty()) {
splashScreenTrace.putAttribute("seasonal_image_url_attribute", "unset");
} else {
splashScreenTrace.putAttribute("seasonal_image_url_attribute", seasonalImageUrl);
}
// ...
}
-
startTrace("splash_seasonal_image_processing")
呼び出しの直後に、splash_seasonal_image_processing
に同じカスタム属性を追加します。
SplashScreenActivity.java
if (!seasonalImageUrl.isEmpty()) {
// TODO: Start the splash_seasonal_image_processing here
final Trace seasonalImageProcessingTrace = FirebasePerformance
.startTrace("splash_seasonal_image_processing");
// TODO: Add a custom attribute "seasonal_image_url_attribute" to splash_seasonal_image_processing
seasonalImageProcessingTrace
.putAttribute("seasonal_image_url_attribute", seasonalImageUrl);
// ...
}
両方のカスタム トレース ( splash_screen_trace
とsplash_seasonal_image_processing
) にカスタム属性 ( seasonal_image_url_attribute
) を追加したので、Android Studio でアプリを再度実行します。 Setting attribute 'seasonal_image_url_attribute' to 'unset' on trace 'splash_screen_trace'.
Remote Config パラメータのseasonalImageUrlをまだ有効にしていないため、属性値はunset
ません。
Performance Monitoring SDK はトレース データを収集し、Firebase に送信します。 Firebase コンソールのパフォーマンスダッシュボードでデータを表示できます。これについては、コードラボの次のステップで詳しく説明します。
7. パフォーマンス監視ダッシュボードを構成する
機能を監視するようにダッシュボードを構成する
Firebase コンソールで、Friendly Eats アプリが含まれるプロジェクトを選択します。
左側のパネルで、 「リリースと監視」セクションを見つけて、 「パフォーマンス」をクリックします。
メトリクス ボードの最初のデータ ポイントを含むパフォーマンスダッシュボードが表示されるはずです。 Performance Monitoring SDK はアプリからパフォーマンス データを収集し、収集後数分以内に表示します。
このメトリクス ボードでは、アプリの主要なメトリクスを追跡できます。デフォルトのビューにはアプリの起動時間トレースの期間が含まれていますが、最も重要なメトリクスを追加できます。追加した新しい機能を追跡しているため、カスタム コード トレースの継続時間splash_screen_trace
を表示するようにダッシュボードを調整できます。
- 空の「メトリックを選択」ボックスのいずれかをクリックします。
- ダイアログ ウィンドウで、トレース タイプとして[カスタム トレース]を選択し、トレース名として
splash_screen_trace
します。
- [Select metric]をクリックすると、
splash_screen_trace
の期間がダッシュボードに追加されていることがわかります。
これらと同じ手順を使用して、関心のある他のメトリクスを追加すると、時間の経過とともに、またリリースが異なる場合でもパフォーマンスがどのように変化するかをすぐに確認できます。
メトリクス ボードは、ユーザーが体験する主要なメトリクスのパフォーマンスを追跡するための強力なツールです。このコードラボでは、狭い時間範囲の小さなデータ セットがあるため、機能ロールアウトのパフォーマンスを理解するのに役立つ他のダッシュボード ビューを使用します。
8. 機能を展開する
モニタリングの設定が完了したので、前に設定した Firebase Remote Config の変更 ( seasonal_image_url)
をロールアウトする準備が整いました。
変更をロールアウトするには、Firebase コンソールの[Remote Config] ページに戻って、ターゲティング条件のユーザー パーセンタイルを増やします。通常、新機能は一部のユーザーに展開し、問題がないと確信できる場合にのみ機能を増やします。ただし、このコードラボでは、アプリのユーザーはあなただけなので、パーセンタイルを 100% に変更できます。
- ページ上部の「条件」タブをクリックします。
- 先ほど追加した
Seasonal image rollout
条件をクリックします。 - パーセンタイルを 100% に変更します。
- [条件を保存]をクリックします。
- [変更を公開]をクリックし、変更を確認します。
Android Studio に戻り、エミュレータでアプリを再起動して新しい機能を確認します。スプラッシュ画面の後に、新しい空の状態のメイン画面が表示されるはずです。
9. パフォーマンスの変化を確認する
次に、Firebase コンソールのパフォーマンスダッシュボードを使用して、スプラッシュ スクリーンの読み込みのパフォーマンスを確認してみましょう。コードラボのこのステップでは、ダッシュボードのさまざまな部分を使用してパフォーマンス データを表示します。
- メインの[ダッシュボード]タブで、トレース テーブルまで下にスクロールし、 [カスタム トレース]タブをクリックします。この表には、前に追加したカスタム コード トレースに加えて、すぐに使用できるトレースがいくつか表示されます。
- 新しい機能を有効にしたので、画像のダウンロードと処理にかかった時間を測定するカスタム コード トレース
splash_seasonal_image_processing
を探します。トレースの[Duration]値から、このダウンロードと処理にはかなりの時間がかかることがわかります。
-
splash_seasonal_image_processing
のデータがあるため、このトレースの期間を[ダッシュボード]タブの上部にあるメトリクス ボードに追加できます。
前と同様に、空の[メトリックを選択]ボックスのいずれかをクリックします。ダイアログ ウィンドウで、トレース タイプとして[カスタム トレース]を選択し、トレース名としてsplash_seasonal_image_processing
選択します。最後に、 [メトリックの選択]をクリックして、このメトリックをメトリック ボードに追加します。
- 違いをさらに確認するには、
splash_screen_trace
のデータを詳しく調べます。メトリクス ボードでsplash_screen_trace
カードをクリックし、 [メトリクスの詳細の表示]をクリックします。
- 詳細ページの左下に、前に作成したカスタム属性を含む属性のリストが表示されます。カスタム属性
seasonal_image_url_attribute
をクリックすると、右側に各季節画像URLのスプラッシュ画面の継続時間が表示されます。
- スプラッシュ スクリーンの継続時間の値は、上記のスクリーンショットの値とはおそらく少し異なるでしょうが、画像が URL からダウンロードされる場合と、デフォルトの画像 (「未設定」で表される) を使用する場合の継続時間は長くなります。
このコードラボでは、この時間が長くなる理由は簡単かもしれませんが、実際のアプリではそれほど明らかではない可能性があります。収集された継続時間データは、さまざまなネットワーク接続条件でアプリを実行しているさまざまなデバイスから取得されますが、これらの条件は予想よりも悪くなる可能性があります。これが現実の状況であれば、この問題をどのように調査するかを考えてみましょう。
- ページの上部にある[パフォーマンス]をクリックして、ダッシュボードのメイン タブに戻ります。
- ページの下部にあるトレース テーブルで、 [ネットワーク リクエスト]タブをクリックします。この表には、アプリからのすべてのネットワーク リクエストが、
images.unsplash.com/**
** URL パターンを含むURL パターンに集約されて表示されます。この応答時間の値を、画像のダウンロードと処理にかかる全体の時間 (つまり、splash_seasonal_image_processing
トレースの継続時間) と比較すると、画像のダウンロードに多くの時間が費やされていることがわかります。
パフォーマンスに関する調査結果
Firebase Performance Monitoring を使用すると、新機能を有効にするとエンド ユーザーに次のような影響が生じることがわかりました。
-
SplashScreenActivity
に費やす時間が増加しました。 -
splash_seasonal_image_processing
の期間は非常に長かったです。 - 遅延の原因は、イメージのダウンロードの応答時間と、イメージに必要な対応する処理時間でした。
次のステップでは、機能をロールバックし、機能の実装を改善する方法を特定することで、パフォーマンスへの影響を軽減します。
10. 機能をロールバックする
スプラッシュ画面中にユーザーの待ち時間が長くなるのは望ましくありません。 Remote Config の主な利点の 1 つは、ユーザーに別のバージョンをリリースすることなく、ロールアウトを一時停止したり元に戻したりできることです。これにより、問題 (最後のステップで発見したパフォーマンスの問題など) に迅速に対応し、不満を抱くユーザーの数を最小限に抑えることができます。
迅速な緩和策として、ロールアウト パーセンタイルを0
にリセットして、すべてのユーザーにデフォルトの画像が再び表示されるようにします。
- Firebase コンソールの[Remote Config]ページに戻ります。
- ページ上部の「条件」をクリックします。
- 先ほど追加した
Seasonal image rollout
条件をクリックします。 - パーセンタイルを0% に変更します。
- [条件を保存]をクリックします。
- [変更を公開]をクリックし、変更を確認します。
Android Studio でアプリを再起動すると、元の空の状態のメイン画面が表示されるはずです。
11.パフォーマンスの問題を修正する
コードラボの前半で、スプラッシュ スクリーンの画像をダウンロードするとアプリの速度が低下することがわかりました。ダウンロードした画像をよく見てみると、2MB を超える画像の元の解像度が使用されていることがわかります。パフォーマンスの問題に対する簡単な解決策の 1 つは、画像のダウンロードにかかる時間を短縮するために、品質をより適切な解像度に下げることです。
Remote Config 値を再度ロールアウトします。
- Firebase コンソールの[Remote Config]ページに戻ります。
-
seasonal_image_url
パラメータの「編集」アイコンをクリックします。 - [季節画像ロールアウトの値]を
https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640
に更新し、 [保存]をクリックします。
- ページ上部の「条件」タブをクリックします。
- [季節画像ロールアウト]をクリックし、パーセンタイルを 100% に戻します。
- [条件を保存]をクリックします。
- 「変更を公開」ボタンをクリックします。
12. 修正をテストし、アラートを設定する
アプリをローカルで実行する
別のダウンロード画像 URL を使用するように新しい構成値を設定して、アプリを再度実行します。今回は、スプラッシュ スクリーンに費やされる時間が以前よりも短いことに気づくはずです。
変更のパフォーマンスを確認する
Firebase コンソールのパフォーマンスダッシュボードに戻って、指標がどのように表示されるかを確認します。
- 今回は、トレース テーブルを使用して詳細ページに移動します。トレース テーブルの下の[カスタム トレース]タブで、カスタム トレース
splash_seasonal_image_processing
をクリックして、期間メトリクスの詳細ビューを再度表示します。
- カスタム属性
seasonal_image_url_attribute
をクリックすると、カスタム属性の内訳が再度表示されます。 URL の上にマウスを置くと、縮小サイズ画像の新しい URL と一致する値が表示されます:https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640
(?w=640
を使用)最後に)。この画像に関連付けられている継続時間の値は、前の画像の値よりもかなり短く、ユーザーにとって許容しやすいものになっています。
- スプラッシュ画面のパフォーマンスが向上したので、トレースが設定したしきい値を超えたときに通知するアラートを設定できます。パフォーマンスダッシュボードを開き、 splash_screen_traceのオーバーフロー メニュー (3 つのドット) アイコンをクリックし、 [アラート設定]をクリックします。
- トグルをクリックして、期間アラートを有効にします。しきい値を、表示されている値より少し高い値に設定して、 splash_screen_traceがしきい値を超えた場合に電子メールを受信するようにします。
- [保存]をクリックしてアラートを作成します。トレース テーブルまで下にスクロールし、 [カスタム トレース]タブをクリックして、アラートが有効になっていることを確認します。
13. おめでとうございます!
おめでとう! Firebase Performance Monitoring SDK を有効にし、新機能のパフォーマンスを測定するためのトレースを収集しました。新機能の展開に向けて主要なパフォーマンス指標を監視し、パフォーマンスの問題が発見された場合には迅速に対応しました。これはすべて、Remote Config で構成を変更し、パフォーマンスの問題をリアルタイムで監視する機能によって可能になりました。
私たちがカバーした内容
- Firebase Performance Monitoring SDK をアプリに追加する
- カスタム コード トレースをコードに追加して特定の機能を測定する
- 新しい機能を制御/ロールアウトするための Remote Config パラメータと条件値のセットアップ
- パフォーマンス監視ダッシュボードを使用してロールアウト中に問題を特定する方法を理解する
- アプリのパフォーマンスが設定したしきい値を超えたときに通知するようにパフォーマンス アラートを設定する