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

为什么我的Flutter应用HTTP网络请求比Postman调用同接口慢很多?

问题核心原因

你当前每次调用顶层http.get方法时,dart的http库会临时创建一个新的HttpClient实例,请求执行完成后立即销毁该实例,因此DNS查询、TCP握手、SSL握手的结果都不会被缓存,每次请求都需要重新走完整的连接建立流程,这就是连接耗时居高不下的根本原因。

优化方案

1. 全局复用HttpClient实例

最直接的解决方案是全局维护同一个http.Client实例,底层会自动管理连接池,复用已建立的连接,自动缓存DNS、TCP、SSL会话信息,同域名后续请求无需重复执行握手流程。
修改后的代码示例:

import 'package:http/http.dart' as http;
import 'dart:convert' as convert;
import 'dart:io';
import 'package:flutter/foundation.dart';

class RoleService with ChangeNotifier {
  NavLinks _navLinks = NavLinks();
  late List<Role> _roles;
  // 全局复用同一个Client实例,不要每次请求都新建
  static final http.Client _sharedClient = http.Client();

  /// Get all Roles
  Future<void> getAllRoles(String authToken) async {
    try {
      var data = await _sharedClient.get(
        Uri.parse("https://api2.example.com/userrel/roles/getall"),
        headers: {HttpHeaders.authorizationHeader: "Bearer $authToken"},
      );
      var jsonData =
          convert.json.decode(data.body).cast<Map<String, dynamic>>();
      _roles = jsonData.map<Role>((json) => Role.fromJson(json)).toList();
      print(_roles);
    } catch (error) {
      print(error);
      rethrow;
    }
  }

  // 仅在应用退出时调用该方法释放资源,不要在单次请求结束后调用
  static void dispose() {
    _sharedClient.close();
  }
}

2. 自定义连接配置(可选,进一步优化)

如果需要更精细化控制连接参数,比如调整长连接保持时间,可以直接基于dart:io的HttpClient自定义配置,再包装为http包可用的Client:

import 'package:http/io_client.dart';
import 'dart:io';

final customHttpClient = HttpClient()
  // 长连接保持时间,建议和AWS API Gateway的空闲超时配置一致(API Gateway默认空闲超时为30秒)
  ..idleTimeout = const Duration(seconds: 120)
  ..connectionTimeout = const Duration(seconds: 10);
final http.Client optimizedClient = IOClient(customHttpClient);

你可以登录AWS控制台将API Gateway的空闲超时调整到和客户端配置匹配的数值,避免连接被服务端提前断开。

3. 开启HTTP/2支持

AWS API Gateway默认支持HTTP/2协议,HTTP/2支持同域名多路复用,所有请求共享同一个连接,性能远高于HTTP 1.1的连接池。Dart的HttpClient默认会自动协商使用HTTP/2,只需确认你在API Gateway控制台已经开启HTTP/2支持即可。

4. 第三方网络库替代(可选)

如果需要更丰富的网络功能,也可以直接使用dio库,它默认内置了连接池复用、请求重试、缓存等能力,配置更简单,无需手动管理Client实例即可实现连接复用。

注意事项

  • 不要在单次请求结束后调用Client的close方法,否则会清空整个连接池,导致复用失效,仅在应用完全退出时调用即可。
  • 如果你的应用涉及多个不同域名的请求,同一个Client实例也可以自动按域名区分连接池,无需为每个域名单独创建Client。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:54:05