You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web从FireStore取数计算耗时过长,求优化方案

Flutter Web 积分计算流程性能优化方案

核心性能瓶颈

当前流程的主要耗时点集中在:

  • 步数计算时每日发起一次Firestore文档请求,日期区间越长请求量越大
  • 用户积分计算串行执行,未利用异步并行能力
  • 循环中频繁调用setState,触发多次UI重绘

针对性优化建议

1. 重构步数查询逻辑,大幅减少Firestore请求

原代码中getStepScores通过Future.forEach循环查询每日步数,每个用户在一个月区间内会发起30+次请求。可以改为一次性获取用户所有步数数据,本地计算分数:

Future<int> getStepScores(String userId, DateTime startDate, DateTime endDate) async {
  List<DateTime> betweenDates = getBetweenDays(startDate, endDate);
  int stepScores = 0;

  // 一次性获取用户所有步数文档,而非每日请求
  final doc = await _db.collection("user_step_count").doc(userId).get();
  if (!doc.exists) return 0;

  final stepData = doc.data()!;
  for (var date in betweenDates) {
    final dateString = "${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}";
    if (stepData.containsKey(dateString)) {
      final dailyStepInt = stepData[dateString] as int;
      stepScores += dailyStepInt < 0
          ? 0
          : dailyStepInt > 10000
              ? 100
              : ((dailyStepInt / 1000).floor()) * 10;
    }
  }

  return stepScores;
}

此优化将步数请求从O(N)降为O(1),N为日期区间天数

2. 用户计算并行化,替换串行循环

原代码通过for循环串行处理每个用户的积分计算,改为用Future.wait并行执行所有用户的计算任务:

// 替换原串行循环
final updatedUsers = await Future.wait(
  userDataList.map((user) => ref
      .read(rankingProvider.notifier)
      .calculateItem(user, firstDateOfMonth, now))
);

// 一次性更新状态
setState(() {
  _initialUserDataListState = false;
  _userContractType = getUserContractType;
  _userContractName = getUserContractName;
  _userDataList.addAll(updatedUsers);
  // 直接在这里完成排序
  _userDataList.sort((a, b) => b!.totalScore.compareTo(a!.totalScore));
});

并行处理能大幅缩短多用户场景下的总耗时,充分利用异步并发能力

3. 优化状态更新逻辑,避免频繁UI重绘

原循环中每处理一个用户就调用setState,会触发多次UI重建。改为所有用户计算完成后一次性更新状态,同时直接在状态更新时完成排序,减少后续操作。

4. 其他细节优化

  • 避免强制解包(!):对stepScore、diaryScore等添加空值判断,避免潜在崩溃同时提升代码稳定性
  • 缓存日期字符串:将日期格式化逻辑封装为工具函数,避免重复计算
  • 提前过滤无效用户:在计算前先过滤掉userId为空的用户,减少无效计算

关于加载页的建议

无论优化与否,都必须添加加载页:

  • 即使优化后,Firestore网络请求仍存在不可控的延迟
  • 加载页能明确告知用户当前处于处理状态,避免用户误以为页面卡顿无响应
  • 可搭配进度指示器(如线性进度条),进一步提升用户体验

内容的提问来源于stack exchange,提问作者Hyejung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:05:15