Flutter页面加载耗时统计

170 阅读3分钟

1. 页面加载效率定义

1.1. 页面加载关键节点

  1. 从页面打开开始(push)
  2. 到业务数据加载完成
  3. 到页面布局完成。业务json渲染完成。
  4. 再到所有图片加载/渲染完成。

1.2. 页面加载耗时定义

  • 业务加载耗时:步骤1开始,到步骤3结束

1.3. 图片加载耗时为什么没有算入耗时?

  • 从技术角度看可以实现,因为监控图片渲染完成,会消耗太多性能,所以不做统计。
  • 为了解决这个问题,我们监控了每个页面的图片下载时间作为补充数据。

2. 页面加载效率的指标有哪些?

2.1. 业务数据加载耗时

页面名称平均加载耗时(ms)P90 加载耗时(ms)加载次数慢加载占比(%)阈值参考说明(ms)状态
首页820190010,00018%⚠️ 正常:<1000,慢:>1500⚠️ 有优化空间
商品详情页125028008,50042%⚠️ 正常:<1200,慢:>1800🚨 需要优化
搜索结果页6009507,2005%✅ 正常:<1000,慢:>1500✅ 良好
个人中心页98016009,30022%⚠️ 正常:<1000,慢:>1500⚠️ 有优化空间
下单结算页155031005,60060%⚠️ 正常:<1200,慢:>1800🚨 严重卡顿

2.2. 📊 移动端图片下载耗时行业参考阈值

阶段/场景平均耗时参考范围说明与建议
局域网 / 高速 Wi-Fi100ms - 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. 🧠 背后逻辑

这个过程包括:

  1. 用户触发页面打开(比如通过 Navigator push)
  2. 页面开始构建 Widget(build)
  3. 发起网络请求加载数据
  4. 等数据加载完成
  5. 页面业务数据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. 🧪 注意事项

  1. 必须初始化 Firebase 和 firebase _ performance 插件
dependencies:
  firebase_core: ^2.0.0
  firebase_performance: ^0.9.0+9
  1. iOS 需要在 AppDelegate 添加配置(如果你是混合栈开发,我可以告诉你怎么加)。
  2. 你可以为多个页面添加不同的 trace 名称,比如 home_page_loaduser_profile_load 等。