http
http copied to clipboard
Http download is 3x times slower on Web vs Desktop
Steps to reproduce
Run code: flutter run --release on Web then click a button, it will download ~18MB file.
Repeat tests on non-web (e.g. desktop platform), download speed shall be much higher.
On my ~40Mbps download connection, Linux maxes out download speed. On Web speed seem to be throttled for some reason.
Linux
Download file http://localhost:8080/20MB.zip
flutter: Downloaded 20971520 in 3975ms
Web
Download file http://localhost:8080/20MB.zip
Downloaded 20971520 in 12xxxms
Dependencies
flutter pub add http
Proxy tunnel required on Web to avoid CORS issue. In order to make this test uniform proxy is used also on non-Web.
mitmproxy -s cors.py --mode reverse:http://xcal1.vodafone.co.uk
cors.py
from mitmproxy import http
def response(flow):
flow.response.headers["Access-Control-Allow-Origin"] = "*"
flow.response.headers["Access-Control-Allow-Headers"] = "*"
Code sample
Code sample
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void activateDownload() async {
// final url = 'http://xcal1.vodafone.co.uk/20MB.zip';
final url = 'http://localhost:8080/20MB.zip'; // Use: `mitmproxy -s cors.py --mode reverse:http://xcal1.vodafone.co.uk` to avoid CORS issues on Web
List<int> buffer = [];
print('\n1) downloadBytesSimple');
print('\nDownload file $url');
await downloadBytesSimple(buffer, url);
}
static Future<void> downloadBytesSimple(List<int> buffer, String url) async {
var headers = {
'Cache-Control': 'no-cache'
};
var startTime = DateTime.timestamp();
final response = await http.get(Uri.parse(url), headers: headers);
print('Downloaded ${response.contentLength} in ${DateTime.timestamp().difference(startTime).inMilliseconds}ms');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
activateDownload();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
What target platforms are you seeing this bug on?
Web
OS/Browser name and version | Device information
Version 123.0.6312.58 (Official Build) (64-bit) Ubuntu 23.10
Does the problem occur on emulator/simulator as well as on physical devices?
Yes
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.19.5, on Ubuntu 23.10 6.5.0-27-generic, locale en_US.UTF-8)
• Flutter version 3.19.5 on channel stable at /opt/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 300451adae (12 days ago), 2024-03-27 21:54:07 -0500
• Engine revision e76c956498
• Dart version 3.3.3
• DevTools version 2.31.1
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /home/tomek/Android/Sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = /home/tomek/Android/Sdk
• Java binary at: /opt/android-studio/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop
• Ubuntu clang version 16.0.6 (15)
• cmake version 3.27.4
• ninja version 1.11.1
• pkg-config version 1.8.1
[✓] Android Studio (version 2023.1)
• Android Studio at /opt/android-studio
• Flutter plugin version 76.3.3
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.7+0-17.0.7b1000.6-10550314)
[✓] VS Code (version 1.78.2)
• VS Code at /usr/share/code
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (2 available)
• Linux (desktop) • linux • linux-x64 • Ubuntu 23.10 6.5.0-27-generic
• Chrome (web) • chrome • web-javascript • Google Chrome 123.0.6312.58
[✓] Network resources
• All expected network resources are available.
• No issues found!
Originally posted here: https://github.com/flutter/flutter/issues/146494
Hi @tomekit
On the browser, we are using a very small wrapper over XMLHTTPRequest so this is most likely a browser issue.
Do you see the same issue when using package:fetch_client?
Unfortunately my environment has changed in the meantime and I no longer can reproduce this problem.
I am currently using Flutter 3.22.0 and Ubuntu 24.04 LTS, previously Flutter 3.19.5 and Ubuntu 23.10
I knot that previously I've tried this on multiple different browsers (Chrome and Firefox) and result were the same (poor download speed on Web).
Currently the speed using the example I've provided above, is somewhat comparable between Web and desktop, although certainly my poor 40Mb/s broadband is a limiting factor.
I've also updated file endpoints, as previous links expired. Since the new links don't handle CORS on Web, I've added a simple mitmproxy command to add them. This also means that transport no longer happen on HTTPS, but when tried some example HTTPS endpoint results were the same.
When v1.3.0 of pkg:http is released (should be soon) we're hoping that the new streaming implementation will improve performance.