监控功能发布期间的表现

1. 概览

在此 Codelab 中,您将学习如何在功能发布期间监控应用的性能。我们的示例应用将具有基本功能,并且已设置为根据 Firebase Remote Config 标志显示不同的背景图片。我们将介绍如何检测轨迹以监控应用性能、向应用推出配置变更、监控效果以及了解如何提升性能。

学习内容

  • 如何将 Firebase Performance Monitoring 添加到移动应用,以获取开箱即用的指标(例如应用启动时间和缓慢或冻结的帧)
  • 如何添加自定义轨迹来了解用户体验历程的关键代码路径
  • 如何使用 Performance Monitoring 信息中心来了解指标并跟踪重要变化(例如功能发布)
  • 如何设置效果提醒以监控关键指标
  • 如何发布 Firebase Remote Config 更改

前提条件

  • Android Studio 4.0 或更高版本
  • 搭载 API 级别 16 或更高级别的 Android 模拟器。
  • Java 版本 8 或更高版本
  • Firebase Remote Config 有基本的了解

2. 设置示例项目

下载代码

运行以下命令以克隆本 Codelab 的示例代码。这将在您的机器上创建一个名为 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 文件的警告。我们将在下一部分中更正此问题。

在此 Codelab 中,您将使用 Firebase Assistant 插件在 Firebase 项目中注册您的 Android 应用,并将必要的 Firebase 配置文件、插件和依赖项添加到您的 Android 项目中 - 所有这些都在 Android Studio 中完成

将应用连接到 Firebase

  1. 依次前往 Android Studio/Help > Check for updates,确保您使用的是最新版 Android Studio 和 Firebase Assistant。
  2. 依次选择 Tools > Firebase 以打开 Assistant 窗格。
    c0e42ef063d21eab.png
  3. 选择要添加到应用的 Performance Monitoring,然后点击开始使用 Performance Monitoring
  4. 点击连接 Firebase,将您的 Android 项目与 Firebase 连接。(这将在浏览器中打开 Firebase 控制台。)
  5. 点击相应按钮以创建新项目,然后输入项目名称(例如 Feature Rollout Performance Codelab)。
  6. 点击继续
  7. 如果看到相关提示,请查看并接受 Firebase 条款,然后点击继续
  8. (可选)在 Firebase 控制台中启用 AI 辅助功能(称为“Gemini in Firebase”)。
  9. 在此 Codelab 中,您不需要使用 Google Analytics,因此请关闭 Google Analytics 选项。
    您可以选择启用 Google Analytics,因为这样可以获得更多 Remote Config 定位选项。不过,此 Codelab 使用的定位选项不需要 Google Analytics。
  10. 接下来,您应该会看到一个对话框,用于将新的 Firebase 应用关联到您的 Android Studio 项目。
    51a549ebde2fe57a.png
  11. 点击连接
  12. 打开 Android Studio。在助理窗格中,您会看到确认信息,表明您的应用已关联到 Firebase。
    40c24c4a56a45990.png

将性能监控添加到您的应用

在 Android Studio 的 Assistant 窗格中,点击 Add Performance Monitoring to your app

您应该会看到一个用于接受更改的对话框,之后 Android Studio 应该会同步您的应用,以确保已添加所有必需的依赖项。

3046f3e1f5fea06f.png

最后,您应该会在 Android Studio 的 Assistant 窗格中看到成功消息,表明所有依赖项都已正确设置。

62e79fd18780e320.png

作为附加步骤,请按照“(可选)启用调试日志记录”步骤中的说明启用调试日志记录。您也可以在公开文档中找到相同的说明。

3. 运行应用

现在,您应该会在应用的模块(应用级)目录中看到 google-services.json 文件,并且应用现在应该可以编译了。在 Android Studio 中,依次点击 Run > Run ‘app',以在 Android 模拟器上构建和运行应用。

应用运行时,您首先会看到如下所示的启动画面:

ffbd413a6983b205.png

然后,几秒钟后,系统会显示包含默认图片的主页:

d946cab0df319e50.png

幕后发生了什么?

启动画面在 SplashScreenActivity 中实现,并执行以下操作:

  1. onCreate() 中,我们初始化 Firebase Remote Config 设置,并提取您将在本 Codelab 后面的 Remote Config 控制台中设置的配置值。
  2. executeTasksBasedOnRC() 中,我们读取 seasonal_image_url 标志的配置值。如果配置值提供了网址,我们会同步下载图片。
  3. 下载完成后,应用会导航到 MainActivity 并调用 finish() 以结束 SplashScreenActivity

MainActivity 中,如果通过 Remote Config 定义了 seasonal_image_url,则该功能将处于启用状态,并且下载的图片将显示为主页的背景。否则,系统会显示默认图片(如上所示)。

4. 设置 Remote Config

现在,您的应用已在运行,您可以设置新的功能标志了。

  1. Firebase 控制台的左侧面板中,找到互动部分,然后点击 Remote Config
  2. 点击创建配置按钮,打开配置表单,然后添加 seasonal_image_url 作为参数键。
  3. 点击添加广告内容描述,然后输入以下广告内容描述:Shows a seasonal image (replaces default) in the main page when the restaurant list is empty.
  4. 依次点击添加新值 -> 条件值 -> 创建新条件
  5. 对于条件名称,请输入 Seasonal image rollout
  6. 对于 Applies if... 部分,选择 User in random percentile <= 0%(您希望在准备好在后续步骤中推出该功能之前,让该功能保持停用状态。)
  7. 点击创建条件。您稍后将使用此条件向用户推出新功能。

7a07526eb9e81623.png

  1. 打开创建您的首个参数表单,然后找到季节性图片发布的值字段。输入将下载季节性图片的网址:https://images.unsplash.com/photo-1552691021-7043334e0b51
  2. 将默认值保留为空字符串。这意味着,系统将显示代码库中的默认图片,而不是从网址下载的图片。
  3. 点击保存

99e6cd2ebcdced.png

您可以看到,新配置已创建为草稿。

  1. 点击发布更改,然后确认顶部的更改,以更新您的应用。

39cd3e96d370c7ce.png

5. 添加对数据加载时间的监控

您的应用会在显示 MainActivity 之前预加载一些数据,并显示启动画面来隐藏此过程。您不希望用户在此界面上等待太长时间,因此通常最好监控启动画面的显示时长。

Firebase Performance Monitoring 就能实现这一点。您可以对自定义代码跟踪记录进行插桩,以监控应用中特定代码的性能,例如数据加载时间和新功能的处理时间。

为了跟踪启动画面显示的时长,您将向 SplashScreenActivity(即实现启动画面的 Activity)添加自定义代码跟踪记录。

  1. 初始化、创建并启动名为 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");
    
    // ...
}
  1. SplashScreenActivityonDestroy() 方法中结束轨迹:

SplashScreenActivity.java

@Override
protected void onDestroy() {
    super.onDestroy();

    // TODO: Stop the splash_screen_trace here
    splashScreenTrace.stop();
}

由于新功能会下载并处理图片,因此您需要添加第二个自定义代码轨迹,以跟踪新功能为 SplashScreenActivity 增加的额外时间。

  1. 初始化、创建并启动名为 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");

        // ...
    }
}
  1. RequestListeneronLoadFailed()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 控制台中过滤跟踪记录的数据。您还可以添加和监控自定义属性

在您的应用中,您刚刚添加了两个自定义代码跟踪记录,用于监控启动画面时长和新功能的处理时间。可能会影响这些时长的因素是所显示的图片是默认图片,还是必须从网址下载的图片。谁知道呢,您最终可能会通过不同的网址下载图片。

因此,我们来为这些自定义代码跟踪记录添加一个表示季节性图片网址的自定义属性。这样,您日后便可按这些值过滤时长数据。

  1. 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);
    }

    // ...
}
  1. 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_tracesplash_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 控制台的“性能”信息中心中查看数据,我们将在本 Codelab 的下一步中详细介绍。

7. 配置性能监控信息中心

配置信息中心以监控功能

Firebase 控制台中,选择包含 Friendly Eats 应用的项目。

在左侧面板中,找到发布和监控部分,然后点击效果

您应该会看到效果信息中心,其中包含指标板中的第一个数据点!Performance Monitoring SDK 会从您的应用收集性能数据,并在收集后的几分钟内显示这些数据。

f57e5450b70034c9.png

您可以在此指标板上跟踪应用的关键指标。默认视图包含应用启动时间跟踪记录的时长,但您可以添加自己最关心的指标。由于您要跟踪添加的新功能,因此可以自定义信息中心以显示自定义代码跟踪记录 splash_screen_trace 的时长。

  1. 点击其中一个空白的选择指标框。
  2. 在对话框窗口中,选择跟踪记录类型 Custom traces 和跟踪记录名称 splash_screen_trace

1fb81f4dba3220e0.png

  1. 点击选择指标,您应该会看到时长为 splash_screen_trace 的指标已添加到信息中心!

您可以使用相同的步骤添加您关心的其他指标,以便快速了解这些指标的效果随时间变化的情况,甚至不同版本之间的变化。

1d465c021e58da3b.png

指标信息中心是一个强大的工具,可用于跟踪用户体验到的关键指标的表现。在此 Codelab 中,您将使用狭窄时间范围内的一小部分数据,因此您将使用其他信息中心视图来帮助您了解功能发布的效果。

8. 推出功能

现在,您已设置好监控,可以推出之前设置的 Firebase Remote Config 更改 (seasonal_image_url)) 了。

如需发布更改,您需要返回 Firebase 控制台中的 Remote Config 页面,增加定位条件的用户百分位数。通常,您会先向一小部分用户发布新功能,只有在确信该功能没有问题时,才会增加发布范围。不过,在此 Codelab 中,您是应用的唯一用户,因此您可以将百分位数更改为 100%。

  1. 点击页面顶部的条件标签页。
  2. 点击您之前添加的 Seasonal image rollout 条件。
  3. 将百分位数更改为 100%。
  4. 点击 Save Condition
  5. 点击发布更改,然后确认更改。

70f993502b27e7a0.png

返回 Android Studio,在模拟器中重启应用,即可看到新功能。在启动画面之后,您应该会看到新的空状态主屏幕!

b0cc91b6e48fb842.png

9. 查看效果变化

现在,我们来使用 Firebase 控制台中的“性能”信息中心查看启动画面加载的性能。在此 Codelab 步骤中,您将使用信息中心的不同部分来查看效果数据。

  1. 在主信息中心标签页上,向下滚动到跟踪记录表,然后点击自定义跟踪记录标签页。在此表中,您将看到之前添加的自定义代码轨迹以及一些开箱即用的轨迹
  2. 现在,您已启用新功能,请查找自定义代码轨迹 splash_seasonal_image_processing,该轨迹用于衡量下载和处理图片所用的时间。从轨迹的时长值可以看出,此下载和处理过程需要相当长的时间。

439adc3ec71805b7.png

  1. 由于您有 splash_seasonal_image_processing 的数据,因此可以将此轨迹的持续时间添加到信息中心标签页顶部的指标板中。

与之前类似,点击其中一个空白的选择指标框。在对话框窗口中,选择轨迹类型自定义轨迹和轨迹名称 splash_seasonal_image_processing。最后,点击选择指标,将此指标添加到指标板。

7fb64d2340410576.png

  1. 如需进一步确认差异,您可以仔细查看 splash_screen_trace 的数据。点击指标信息中心内的 splash_screen_trace 卡片,然后点击查看指标详情

b1c275c30679062a.png

  1. 在详情页面中,您会在左下角看到一个属性列表,其中包括您之前创建的自定义属性。点击自定义属性 seasonal_image_url_attribute,即可在右侧查看每个季节性图片网址的启动画面时长:

8fa1a69019bb045e.png

  1. 您的启动画面时长值可能与上图中的值略有不同,但与使用默认图片(以“未设置”表示)相比,从网址下载图片时,您应该会获得更长的时长

在此 Codelab 中,这种较长时间的原因可能很简单,但在实际应用中,原因可能并不那么明显。收集的时长数据将来自不同的设备,这些设备在各种网络连接条件下运行应用,而这些条件可能比您预期的要差。我们来看看在实际情况下,您会如何调查此问题。

  1. 点击页面顶部的效果,返回信息中心主标签页:640b696b79d90103.png
  2. 在页面底部的轨迹表中,点击网络请求标签页。在此表中,您会看到应用的所有网络请求汇总为网址格式,包括 images.unsplash.com/** 网址格式。如果您将此响应时间的值与图片下载和处理所需的总时间(即 splash_seasonal_image_processing 轨迹的持续时间)进行比较,就会发现大部分时间都花在了下载图片上。

6f92ce0f23494507.png

效果分析

使用 Firebase 性能监控,您发现启用新功能后,最终用户会受到以下影响:

  1. SplashScreenActivity上花费的时间有所增加。
  2. splash_seasonal_image_processing 的时长非常长。
  3. 延迟是由于图片下载的响应时间以及图片所需的相应处理时间造成的。

在下一步中,您将通过回滚该功能来减轻对性能的影响,并确定如何改进该功能的实现。

10. 回滚功能

在启动画面期间增加用户的等待时间是不理想的。Remote Config 的一项主要优势是,您可以暂停和撤消发布,而无需向用户发布另一个版本。这样一来,您就可以快速应对问题(例如在上一步中发现的性能问题),并尽可能减少不满意的用户数量。

作为快速缓解措施,您将发布百分比重置回 0,以便所有用户再次看到默认图片:

  1. 返回 Firebase 控制台中的 Remote Config 页面
  2. 点击页面顶部的条件
  3. 点击您之前添加的 Seasonal image rollout 条件。
  4. 将百分位数更改为 0%
  5. 点击 Save Condition
  6. 点击发布更改,然后确认更改。

18c4f1cbac955a04.png

在 Android Studio 中重启应用,您应该会看到原来的空白状态主屏幕:

d946cab0df319e50.png

11. 解决性能问题

您在本 Codelab 中早些时候发现,下载启动画面图片会导致应用运行缓慢。仔细查看下载的图片后,您会发现自己使用的是图片的原始分辨率,图片大小超过 2MB!解决性能问题的一种快速方法是将画质降低到更合适的分辨率,这样图片下载所需的时间就会更少。

再次推出 Remote Config 值

  1. 返回 Firebase 控制台中的 Remote Config 页面
  2. 点击 seasonal_image_url 参数对应的 Edit(修改)图标。
  3. 季节性图片发布的值更新为 https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640,然后点击保存

828dd1951a2ec4a4.png

  1. 点击页面顶部的条件标签页。
  2. 点击季节性图片发布,然后将百分位重新设置为 100%。
  3. 点击 Save Condition

1974fa3bb789f36c.png

  1. 点击发布更改按钮。

12. 测试修复并设置提醒

在本地运行应用

将新配置值设置为使用其他下载图片网址后,再次运行应用。这次,您应该会注意到,在启动画面上花费的时间比之前短。

b0cc91b6e48fb842.png

查看更改的效果

返回 Firebase 控制台中的“性能”信息中心,查看指标的显示效果。

  1. 这次,您将使用轨迹表导航到详情页面。在跟踪记录表格下方的“自定义跟踪记录”标签页中,点击自定义跟踪记录 splash_seasonal_image_processing,再次查看其时长指标的更详细视图。

2d7aaca03112c062.png

  1. 点击自定义属性 seasonal_image_url_attribute 可再次查看自定义属性的细分数据。如果您将光标悬停在网址上,会看到一个与缩小尺寸后的图片的新网址相符的值:https://images.unsplash.com/photo-1552691021-7043334e0b51?w=640(末尾带有 ?w=640)。与上张图片相比,此图片关联的时长值明显缩短,用户更容易接受!

10e30c037a4237a2.png

  1. 现在,您已改进启动画面性能,可以设置提醒,以便在跟踪记录超出您设置的阈值时收到通知。打开效果信息中心,然后点击 splash_screen_trace 的溢出菜单(三点状)图标,再点击提醒设置

4bd0a2a1faa14479.png

  1. 点击切换开关以启用时长提醒。将阈值设置为略高于您之前看到的 splash_screen_trace 值,这样一来,如果 splash_screen_trace 超过阈值,您就会收到电子邮件。
  1. 点击保存以创建提醒。向下滚动到轨迹表,然后点击自定义轨迹标签页,您会看到提醒已启用!

2bb93639e2218d1.png

13. 恭喜!

恭喜!您已启用 Firebase Performance Monitoring SDK 并收集了轨迹,以衡量新功能的性能!您在推出新功能时监控了关键效果指标,并在发现效果问题时迅速做出了反应。借助 Remote Config 更改配置以及实时监控性能问题,这一切都得以实现。

所学内容

  • 将 Firebase Performance Monitoring SDK 添加到您的应用
  • 向代码添加自定义代码跟踪记录以衡量特定功能
  • 设置 Remote Config 参数和条件值以控制/推出新功能
  • 了解如何使用 Performance Monitoring 信息中心在发布期间发现问题
  • 设置性能提醒,以便在应用性能超出您设置的阈值时收到通知

了解详情