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

如何在Flutter中优化产品API调用,解决加载耗时过长问题?

优化Flutter中产品与价格API调用的方案

当前核心问题是多次独立价格API请求导致整体加载耗时过长,以下是按优先级排序的可落地优化方案:

1. 后端新增批量价格查询接口(最优解)

这是效率最高的优化方式,直接减少HTTP请求数量。建议后端提供批量接口:

  • 请求方式:POST
  • 接口地址:https://api.example.com/api/v1/Products/prices
  • 请求体:{"productIds": ["id1", "id2", ...], "quantity": 1}
  • 返回格式:按产品ID映射的价格数据,如{"id1": {...priceData}, "id2": {...priceData}}

前端改造代码示例:

if (resp.statusCode == 200) {
  final data = jsonDecode(resp.body) as List;
  final productItems = data.map((item) => Product.fromJson(item)).toList();
  
  // 批量请求价格
  final productIds = productItems.map((p) => p.id).where((id) => id != null).cast<String>().toList();
  var priceResp = await oauth2Helper.post(
    "https://api.example.com/api/v1/Products/prices",
    body: jsonEncode({"productIds": productIds, "quantity": 1}),
  );
  
  if (priceResp.statusCode == 200) {
    final priceMap = jsonDecode(priceResp.body) as Map<String, dynamic>;
    for (var product in productItems) {
      if (product.id != null && priceMap.containsKey(product.id)) {
        product.price = Price.fromJson(priceMap[product.id!]);
      }
    }
  }
  
  productList.addAll(productItems);
  Navigator.push(
    context,
    MaterialPageRoute(
        builder: (context) => ProductsPage(productList: productList, customer: customer)),
  );
}

2. 前端控制并发请求数(后端无法修改时用)

一次性发起多个请求可能触发后端限流或客户端网络拥堵,可限制同时发起的请求数量:

// 控制并发数的工具函数
Future<void> runWithConcurrency<T>(List<Future<T> Function()> tasks, int concurrency) async {
  final running = <Future<T>>[];
  for (final task in tasks) {
    running.add(task());
    if (running.length >= concurrency) {
      await Future.any(running);
      running.removeWhere((f) => f.isCompleted);
    }
  }
  await Future.wait(running);
}

// 在loadPage中替换原价格加载逻辑
final priceTasks = productItems.map((product) => () => product.loadPrice()).toList();
await runWithConcurrency(priceTasks, 2); // 限制同时发起2个请求

3. 延迟加载价格(提升用户体验)

无需等所有价格加载完成再跳转页面,先展示产品基本信息,价格后续异步加载:

// ProductsPage中的产品列表项组件
class ProductItem extends StatefulWidget {
  final Product product;
  const ProductItem({super.key, required this.product});

  @override
  State<ProductItem> createState() => _ProductItemState();
}

class _ProductItemState extends State<ProductItem> {
  @override
  void initState() {
    super.initState();
    _loadPrice();
  }

  Future<void> _loadPrice() async {
    await widget.product.loadPrice();
    if (mounted) setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(widget.product.name ?? ''),
      subtitle: widget.product.price != null 
          ? Text("${widget.product.price!.value}") 
          : const CircularProgressIndicator(size: 16),
    );
  }
}

4. 缓存价格数据

对用户可能重复查看的产品,将价格缓存到本地,避免重复请求:

// 修改Product的loadPrice方法
Future<void> loadPrice() async {
  // 先读取缓存
  final cachedPrice = await _getCachedPrice(id!);
  if (cachedPrice != null) {
    price = cachedPrice;
    return;
  }

  var resp = await oauth2Helper.get("https://api.example.com/api/v1/Products/${id}/price?quantity=1");
  if (resp.statusCode == 200) {
    final data = jsonDecode(resp.body);
    price = Price.fromJson(data);
    // 缓存1小时
    await _cachePrice(id!, price!, DateTime.now().add(const Duration(hours: 1)));
  } else {
    print("Error loading price for product $id");
  }
}

// 缓存工具方法(基于SharedPreferences)
Future<Price?> _getCachedPrice(String productId) async {
  final prefs = await SharedPreferences.getInstance();
  final jsonStr = prefs.getString("price_$productId");
  final expireTimeStr = prefs.getString("price_expire_$productId");
  if (jsonStr == null || expireTimeStr == null) return null;
  
  final expireTime = DateTime.parse(expireTimeStr);
  if (DateTime.now().isAfter(expireTime)) {
    prefs.remove("price_$productId");
    prefs.remove("price_expire_$productId");
    return null;
  }
  
  return Price.fromJson(jsonDecode(jsonStr));
}

Future<void> _cachePrice(String productId, Price price, DateTime expireTime) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString("price_$productId", jsonEncode(price.toJson()));
  await prefs.setString("price_expire_$productId", expireTime.toIso8601String());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:08:11