Firebase Performance Monitoring 是 Firebase 平台中内置的工具,用于实时自动收集和分析移动应用的性能指标。与基于 logcat 或 Xcode Instruments 的自建解决方案不同,Performance SDK 无需修改业务逻辑即可测量应用启动时间、HTTP 请求持续时间、屏幕渲染速度和自定义场景。根据 Google Firebase (2026),该服务用于 40% 的 Firebase 项目,用于识别瓶颈并将应用性能维持在目标水平。
要点
Firebase Performance Monitoring 是一个 SDK 和云平台,用于收集、聚合和可视化移动应用的性能指标。SDK 嵌入到应用中,自动对关键点进行插桩:Activity(Android)或 ViewController(iOS)的生命周期、通过 URLSession(iOS)或 OkHttp(Android)的网络请求以及系统调用。收集的数据发送到 Firebase 服务器,在那里按应用版本、设备、国家和其他属性进行聚合。
Performance SDK 的架构基于最小开销原则:插桩在所测量操作的执行时间上增加不超过 1-2%。数据在后台异步收集并在发送前缓存在设备上,从而消除对 UI 线程性能的影响。数据按计划发送(默认每 30 分钟一次)或当缓冲区达到 100 KB 时发送。
Firebase Performance 与 Android Studio(CPU Profiler)或 Xcode Instruments 分析工具的主要区别在于生产监控。Firebase Performance 从真实用户设备收集数据,而不仅仅是从开发者设备。这可以检测仅在特定型号、操作系统版本或特定区域出现的问题——即在受控环境中无法重现的问题。
自动插桩是 Firebase Performance 的主要特性。对于 Android,SDK 自动注册 ActivityLifecycleCallbacks 并测量 onCreate 和 onResume 之间的时间(屏幕渲染时间)。对于 iOS —— 对 viewDidLoad 和 viewDidAppear 方法进行 swizzle。网络请求在 OkHttpInterceptor(Android)或 NSURLProtocol(iOS)级别被拦截。开发者无需为标准指标添加 start/stop 调用。
启用和禁用 Performance SDK 通过 Google Services 插件(Android)或 Info.plist(iOS)进行管理。为了调试,可以启用 Performance SDK 的详细日志记录,它将显示正在收集和发送哪些指标。在生产环境中,建议将日志记录保持在 warning 级别,以免日志被不必要的信息填满。对于 Flutter 或 React Native 项目,自动插桩可能受限——更多细节请参见代码示例部分。
Firebase Performance 在免费的 Spark 套餐中提供,对跟踪数量或数据量没有限制。付费的 Blaze 套餐也无需为 Performance Monitoring 付费——这是为数不多的在两个套餐中都完全免费的 Firebase 服务之一。只有一个限制:数据保存 30 天(Spark)和最多 365 天(Blaze)。对于长期分析,通过 BigQuery export 导出数据。
免费使 Firebase Performance 成为任何项目的理想选择——从原型到拥有数百万用户的企业级应用。唯一的成本项是 Performance SDK 数据的出站流量,但与应用的其他网络操作相比可以忽略不计(每台设备每月少于 1 MB)。在 BigQuery export 中,存储和查询会产生费用,但 Performance SDK 本身是免费的。
Firebase Performance 自动收集五类指标,无需编写一行代码:应用启动时间(app start)、慢请求(slow HTTP requests)、屏幕渲染速度(screen rendering)、内存使用(memory usage,仅 Android)和帧率(frame rate,仅 Android)。这些指标在连接 SDK 和首次用户会话后立即可在 Firebase 控制台中使用。
App Start Time —— 从进程启动到 UI 完全准备好进行交互的时间。分为冷启动(应用从零开始启动)和热启动(应用从后台状态恢复)。冷启动包括加载 DEX 文件、初始化静态字段、调用 Application.onCreate 和 Activity.onCreate。Firebase 自动对启动类型进行分类,并显示每种类型的时间分布。
Screen Rendering Time —— 从开始加载屏幕(Android 的 onCreate,iOS 的 viewDidLoad)到屏幕准备好进行交互(onResume,viewDidAppear)的时间。Firebase 聚合每个屏幕的数据(按类名或自定义屏幕名称),从而可以确定哪个屏幕加载最慢。对于 Android,还测量丢帧(dropped frames)—— 屏幕渲染期间跳过的帧数(jank)。
| 指标 | Android | iOS | 显示内容 |
|---|---|---|---|
| App Start | 是 | 是 | 冷启动和热启动时间 |
| Screen Rendering | 是 | 是 | 每个屏幕的显示速度 |
| HTTP Requests | 是 | 是 | 每个网络请求的指标 |
| Dropped Frames | 是 | 否 | 跳帧(jank) |
| Memory Usage | 是 | 否 | 会话中的 RAM 使用情况 |
Performance SDK 自动拦截和测量通过 URLSession、OkHttp 或 URLConnection 从应用发送的每个 HTTP/HTTPS 请求。每个请求记录:URL(出于安全考虑不带查询参数的路径)、HTTP 方法、响应代码、以字节为单位的响应大小、请求持续时间和连接速度(WiFi、蜂窝网络)。数据在 Firebase 控制台的 “Network Requests” 仪表板中聚合。
Slow Requests —— 持续时间超过设定阈值的请求。“慢请求”的默认阈值是 4000 毫秒。该指标对于识别服务器端问题至关重要:如果后端更新后慢请求的数量从 1% 增加到 15%,这是立即分析服务器日志的信号。用户不会等待超过 5 秒的响应——Firebase 数据显示,如果请求超过 3 秒,53% 的用户会关闭应用。
iOS 限制:在 iOS 上,Performance SDK 无法测量丢帧(这是私有 API)。要在 iOS 上测量 jank,请使用 MetricKit 或 CADisplayLink。此外,在 iOS 上,SDK 不会拦截通过不使用 URLSession 的第三方 HTTP 客户端(例如 SwiftNIO)执行的请求。对于此类情况,请使用带有 HTTP 属性的自定义跟踪。
Android 限制:在 Android 上,自动内存测量仅在 Android 8.0+(API 26+)设备上可用。对于旧版本,请使用通过 Debug.getMemoryInfo() 获取数据的自定义跟踪。SDK 也不会拦截 WebSocket 连接——它们需要单独的跟踪。尽管存在限制,自动指标仍可满足 80% 的性能监控需求。
自定义跟踪(custom traces)是开发人员手动创建的命名时间间隔,用于测量特定场景的性能:加载新闻信息流、处理图像、同步数据、执行复杂的数据库查询。自定义跟踪补充了自动指标,并允许测量开发人员认为对性能至关重要的代码部分。
每个跟踪都有一个名称(最多 100 个字符),并且可以包含最多 5 个自定义指标(metrics)—— 在跟踪内记录的数值。例如,在 “image_processing” 跟踪中可以测量 “original_file_size” 和 “processed_file_size” 指标。指标在 Firebase 控制台中显示为分布(最小值、最大值、平均值、百分位数),从而可以分析不仅是持续时间,还有操作的特性。
HTTP 属性是一种特殊类型的自定义跟踪,用于 SDK 未自动拦截的网络请求(例如通过 WebSocket 或第三方库)。HTTP 属性包括 URL、HTTP 方法、响应代码和响应大小。Firebase 将它们显示在 “Network Requests” 部分,与自动收集的请求一起,提供网络交互的统一视图。
自定义跟踪对于测量以下内容必不可少:从本地数据库(Room、CoreData)加载数据的时间、复杂计算(加密、压缩)的持续时间、动画和过渡的性能、第三方 SDK(地图、支付、分析)的响应时间。对于每个此类场景,创建一个跟踪,将测量代码包裹在 start/stop 中,并添加属性以备后续分段。
不要滥用自定义跟踪。每个跟踪都意味着额外的电池和数据消耗。建议在应用的正式版本中不超过 10–15 个活动跟踪。为了调试,可以添加更多跟踪,但在发布之前,通过 Remote Config 禁用多余的跟踪(使用 performance_tracing_enabled 标志)。这允许仅为选定的用户或会话启用详细跟踪,而不影响所有用户。
自定义属性(custom attributes)是可以添加到跟踪中的键值对,用于在 Firebase 控制台中进行后续过滤。例如,可以向 “feed_load” 跟踪添加 “feed_type”(main、explore、following)和 “cache_status”(cold、warm)属性。在控制台中,可以按这些属性过滤跟踪数据,以确定哪种信息流类型加载最慢。
限制:每个跟踪最多可以有 5 个自定义属性。属性值是长度不超过 100 个字符的字符串。属性必须在跟踪开始之前设置;跟踪开始后更改属性将被忽略。此限制与性能有关:跟踪开始后设置属性将需要额外的同步。
阈值(thresholds)是可配置的指标边界值,当超过时 Firebase Performance 会生成警告。阈值在 Firebase 控制台(Performance > Thresholds 部分)中为每个自动指标设置:app start time(cold/warm)、screen rendering time、slow HTTP requests、HTTP response time。可以为所有应用版本设置全局阈值,也可以为特定版本设置特定阈值。
警报(alerts)是 Firebase 在超过阈值时发送的自动通知。警报可以配置为通过电子邮件、Slack webhook、PagerDuty 或 Cloud Functions(用于自定义处理)发送。每个警报包含:指标名称、当前值、阈值、应用版本、分段(设备、国家)。警报允许在性能退化被用户注意到之前做出响应。
推荐阈值根据行业标准(Google I/O 2025):冷启动 — 少于 2 秒,热启动 — 少于 1 秒,屏幕渲染 — 少于 500 毫秒,HTTP 请求持续时间 — 少于 3000 毫秒(第 95 百分位),慢请求比例 — 少于 5%。对于高竞争性应用(社交、电商),目标阈值可能更严格:冷启动 < 1.5 秒,HTTP < 1000 毫秒。
在 Firebase 控制台中转到 Performance 部分,打开 Thresholds 选项卡。为每个指标设置所需的阈值和应受超限影响的用户百分比。例如:“如果冷启动超过 2 秒且影响超过 10% 的用户,则认为冷启动缓慢”。Firebase 将显示当前指标值和超限历史记录,以帮助选择切合实际的阈值。
重要:阈值不会影响数据收集,它们只管理通知的生成。如果阈值太低(例如,冷启动 1 秒,而 50% 的设备在 3 秒内启动),警报将不断到来,变成开发人员不再注意的“噪音”。根据当前指标设置阈值,然后在优化应用时逐步收紧阈值。
Performance 仪表板以时间序列显示关键指标,并按应用版本、设备、国家、连接类型和操作系统版本进行细分。每个指标都提供:平均值、中位数、第 95 百分位、第 99 百分位。第 95 百分位是评估性能信息量最大的指标,因为它显示了应用在“弱设备”上的表现,忽略了异常值。
仪表板支持版本比较:选择两个应用版本(当前和之前)以直观比较指标。如果更新后启动时间的第 95 百分位从 2.1 秒增加到 3.4 秒 — 回退很明显,需要找到导致减速的提交。Firebase Performance 与 GitHub、GitLab 和 Bitbucket 集成,从而可以将指标变化与特定提交关联起来。
让我们看看 Kotlin 语言 Android 应用中的 Firebase Performance Monitoring 集成示例。代码演示了创建自定义跟踪以测量新闻信息流加载、为未自动拦截的请求添加 HTTP 属性以及使用 Trace 测量图像处理时间。所有示例都考虑了通过 Remote Config 禁用跟踪的可能性。
使用前添加依赖:implementation("com.google.firebase:firebase-perf") 通过 Firebase BOM。对于自动插桩,无需额外配置 — SDK 在连接依赖后自动拦截标准操作。
第一个示例 — 测量从服务器加载新闻信息流的加载时间。跟踪包裹了异步操作 fetchFeed,该操作从网络获取数据并解析 JSON。跟踪添加了自定义属性:数据源(cache 或 network)和接收的帖子数量。这允许对数据进行分段,并了解信息流在什么条件下加载最慢。
suspend fun loadFeedWithTrace(source: String) {
val trace = Firebase.performance
.newTrace("feed_load")
trace.putAttribute("source", source)
try {
trace.start()
val feed = fetchFeed()
trace.putMetric(
"items_count",
feed.size.toLong()
)
} finally {
trace.stop()
}
}
loadFeedWithTrace 函数接收 source 参数(“cache” 或 “network”),该参数用作跟踪属性。异步操作完成后,跟踪在 finally 块中停止,即使在异常情况下也能保证停止。items_count 指标允许分析帖子数量如何影响加载时间。在 Firebase 控制台中,可以按 source 属性过滤跟踪,并看到从网络加载比从缓存慢 3 倍。
第二个示例 — 通过 WebSocket 执行的请求的 HTTP 属性(不会被自动拦截)。使用 HttpMetric 类,它允许手动注册 URL 请求、其方法、响应代码和大小。Firebase 将该请求与自动拦截的请求一起显示在 Network Requests 部分。
suspend fun sendWithHttpMetric() {
val metric = Firebase.performance
.newHttpMetric(
"https://api.example.com/data",
FirebasePerformance.HttpMethod.POST
)
metric.start()
try {
val response = webSocketSend()
metric.setHttpResponseCode(response.code)
metric.setRequestPayloadSize(1024)
metric.setResponsePayloadSize(
response.body.length.toLong()
)
} finally {
metric.stop()
}
}
在示例中,sendWithHttpMetric 使用 newHttpMetric 注册非标准 HTTP 调用。SDK 不会自动拦截它,因此开发人员手动设置 URL、方法、响应代码和大小。务必设置不带查询参数的 URL(为了安全和聚合)— 即 /data,而不是 /data?token=abc。Firebase 自动对相似的 URL 模式进行分组。
第三个示例演示了使用自定义跟踪测量图像处理时间(压缩、调整大小)。在这种情况下,跟踪包裹了同步操作,但对于生产环境,请使用协程或 RxJava 以不阻塞 UI 线程。
fun compressImage(bitmap: Bitmap): ByteArray {
val trace = Firebase.performance
.newTrace("image_compression")
trace.putAttribute(
"format", "JPEG"
)
trace.start()
val stream = ByteArrayOutputStream()
bitmap.compress(
Bitmap.CompressFormat.JPEG, 80, stream
)
val result = stream.toByteArray()
trace.putMetric(
"output_size_kb",
result.size / 1024.toLong()
)
trace.stop()
return result
}
compressImage 函数测量将图像压缩为 80% 质量的 JPEG 的时间。format 属性允许将来比较 JPEG 与 WebP 的压缩时间。output_size_kb 指标显示压缩的效率。在 Firebase 控制台中可以看到分布:在弱设备(低端 Android)上,压缩时间比旗舰设备长 4 倍,这可能是将图像发送到服务器时延迟的原因。
Firebase Performance 提供数据,但不提供现成的解决方案。指标分析需要了解每个指标性能退化的典型原因。让我们看看基于 Performance Monitoring 数据的主要退化模式及其诊断方法。方法:在指标中发现异常 → 检查典型原因 → 应用优化 → 一周后检查结果。
冷启动缓慢(超过 2 秒):原因 — Application.onCreate 中的重型 SDK 初始化(分析、崩溃报告、地图 SDK)、加载大型资源(字体、主题)、启动时主线程中的同步操作。解决方案:延迟 SDK 初始化、推迟资源加载、使用 SplashScreen API(Android 12+)在初始化期间显示占位符。Firebase Performance 将显示哪个应用版本启动更慢 — 检查添加或更新了哪些依赖项。
屏幕渲染缓慢(超过 500 毫秒):原因 — 复杂的 View 层次结构(嵌套的 ConstraintLayout、大量 Fragment)、在 UI 线程中加载数据(网络或磁盘)、繁重的绘制操作(大图像、自定义 View)。解决方案:优化布局层次结构(Android Studio 中的 Layout Inspector)、将数据移到后台线程、通过 Glide 或 Coil 缓存图像。使用 Firebase 中的 Screen Rendering 过滤器找到最慢的屏幕并首先优化它。
HTTP 请求缓慢(超过 3 秒):原因 — 服务器慢、有效载荷大、缺少缓存、协议不优化(HTTP/1.1 而非 HTTP/2)、DNS 解析。解决方案:检查服务器端(正常运行时间、延迟)、减小响应大小(分页、GraphQL、protobuf 替代 JSON)、通过 HTTP 头(Cache-Control)启用缓存、使用 OkHttp Interceptor 添加超时和重试逻辑。
Firebase Performance 显示请求的时间分布:DNS 解析、TCP 握手、TLS 握手、请求发送、响应接收。如果大部分时间花在 DNS 上 — 使用 DNS 预加载(OkHttp DNS-over-HTTPS)。如果花在 TLS 上 — 使用会话恢复和密码套件调整。如果花在响应接收上 — 检查响应大小和用户的网络速度。Firebase 数据允许在协议级别定位问题,而不仅仅是说“请求慢”。
对于生产环境,建议添加 Remote Config 标志 performance_tracing_enabled,用于远程禁用自定义跟踪。如果客户端上的 Firebase Performance SDK 生成过多数据或影响性能(在弱设备上),可以为所有用户禁用跟踪,只留下开销最小的自动指标。
逻辑示例:在应用启动时,检查 Remote Config 参数 performance_tracing_enabled。如果为 false — 所有 Firebase.performance.newTrace() 调用返回一个不收集数据的桩对象。这通过一个包装类实现,该类在创建跟踪之前检查标志。这种方法允许为特定用户(beta 测试人员、开发人员)启用详细跟踪,而不影响整个用户群。
常见问题
SDK 开销最小 — 不到测量操作时间的 1–2%。数据在后台线程中异步收集并在设备上缓存。对于拥有数百万用户的生产应用,SDK 的额外负载可以忽略不计,不会影响用户体验。
在免费 Spark 套餐中 — 30 天,在付费 Blaze 套餐中 — 最多 365 天。对于长期存储和分析,使用 BigQuery export:Performance 数据可以导出到 BigQuery 并无限期存储(单独收费)。
可以,通过 Android 和 iOS 的原生 SDK。firebase_performance Flutter 插件为自定义跟踪和 HTTP 属性提供 API。自动指标(app start、screen rendering)仅通过原生 SDK 提供,不覆盖 Flutter 层。要完全监控 Flutter,请将 DevTools 与 Firebase Performance 一起使用。
在 Firebase 控制台(Performance > Thresholds)中为指标设置阈值,并配置通知渠道:电子邮件、Slack、PagerDuty、Cloud Functions。建议为冷启动和慢 HTTP 请求比例配置警报 — 这些是对用户体验最关键的性能指标。
主要原因:SDK 未添加到项目中,应用未在物理设备上运行(模拟器可能不发送数据),首次运行未满 12 小时(数据在一天内出现),设备上网络被阻止(防火墙、VPN)。检查 SDK 日志:在调试版本中启用 Performance SDK 的详细日志记录。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。