1. 页面加载效率定义
1.1. 页面加载关键节点
- 从页面打开开始(push)
- 到业务数据加载完成
- 到页面布局完成。业务json渲染完成。
- 再到所有图片加载/渲染完成。
1.2. 页面加载耗时定义
- 业务加载耗时:步骤1开始,到步骤3结束
1.3. 图片加载耗时为什么没有算入耗时?
- 从技术角度看可以实现,因为监控图片渲染完成,会消耗太多性能,所以不做统计。
- 为了解决这个问题,我们监控了每个页面的图片下载时间作为补充数据。
2. 页面加载效率的指标有哪些?
2.1. 业务数据加载耗时
| 页面名称 | 平均加载耗时(ms) | P90 加载耗时(ms) | 加载次数 | 慢加载占比(%) | 阈值参考说明(ms) | 状态 |
|---|---|---|---|---|---|---|
| 首页 | 820 | 1900 | 10,000 | 18% | ⚠️ 正常:<1000,慢:>1500 | ⚠️ 有优化空间 |
| 商品详情页 | 1250 | 2800 | 8,500 | 42% | ⚠️ 正常:<1200,慢:>1800 | 🚨 需要优化 |
| 搜索结果页 | 600 | 950 | 7,200 | 5% | ✅ 正常:<1000,慢:>1500 | ✅ 良好 |
| 个人中心页 | 980 | 1600 | 9,300 | 22% | ⚠️ 正常:<1000,慢:>1500 | ⚠️ 有优化空间 |
| 下单结算页 | 1550 | 3100 | 5,600 | 60% | ⚠️ 正常:<1200,慢:>1800 | 🚨 严重卡顿 |
2.2. 📊 移动端图片下载耗时行业参考阈值
| 阶段/场景 | 平均耗时参考范围 | 说明与建议 |
|---|---|---|
| 局域网 / 高速 Wi-Fi | 100ms - 300ms | 理想情况下图片能在 0.1s ~ 0.3s 内加载完成,用户体验最好 |
| 4G / 5G 网络环境 | 300ms - 800ms | 移动网络下,300ms~800ms 是常见范围,超出 1s 则体验开始变差 |
| 弱网环境(3G/2G) | 1s - 3s | 网络条件较差,图片加载可接受范围延长,建议尽量压缩图片并使用占位图 |
| 缓存命中时 | <50ms | 图片缓存命中(内存或磁盘)几乎即时加载,理想阈值 |
2.3. 总结
因为我们的目标是秒开,所以:
- 业务数据渲染耗时需要300ms内完成
- 图片在700ms内完成
3. 如何获取页面业务数据加载耗时
3.1. ✅ 你的需求翻译成技术目标是:
监控页面从“开始打开”到“业务JSOn数据加载完成并渲染完 UI”的总耗时。
3.2. 🧠 背后逻辑
这个过程包括:
- 用户触发页面打开(比如通过 Navigator push)
- 页面开始构建 Widget(build)
- 发起网络请求加载数据
- 等数据加载完成
- 页面业务数据JSON完成首次渲染(即
addPostFrameCallback被调用)
所以我们需要在:
- 步骤 1 开始打点
- 步骤 5 停止打点
并把这段耗时作为 Firebase 的 自定义 Trace 上报。
3.3. ✅ Flutter 代码实现(推荐)
3.3.1. 1. 在你的页面里添加 trace 打点
import 'package:firebase_performance/firebase_performance.dart';
class MyPage extends StatefulWidget {
const MyPage({super.key});
@override
State<MyPage> createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
Trace? _trace;
@override
void initState() {
super.initState();
_startPageTrace();
_loadData();
}
Future<void> _startPageTrace() async {
_trace = FirebasePerformance.instance.newTrace("my_page_full_load");
await _trace!.start();
}
Future<void> _loadData() async {
// 模拟网络请求
await Future.delayed(const Duration(seconds: 2));
// 等数据加载完后,等一帧渲染完成再结束 trace
WidgetsBinding.instance.addPostFrameCallback((_) async {
await _trace?.stop();
});
setState(() {
// 渲染数据
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("我的页面")),
body: const Center(child: Text("页面内容加载完成")),
);
}
}
3.4. 📊 你将看到:
- 平均耗时
- 最大耗时
- 90%、95%、99% 分位耗时
- 设备型号、国家、网络类型、系统版本 等分布
3.5. 🧪 注意事项
- 必须初始化 Firebase 和 firebase _ performance 插件
dependencies:
firebase_core: ^2.0.0
firebase_performance: ^0.9.0+9
- iOS 需要在
AppDelegate添加配置(如果你是混合栈开发,我可以告诉你怎么加)。 - 你可以为多个页面添加不同的 trace 名称,比如
home_page_load、user_profile_load等。