This test analyzes the performance impact of the load in Dart's thread over the requests from different HTTP clients.
- Flutter 3.0.2
- Dart 2.17.3
- async 2.8.2
- dio 4.0.6
- flutter_isolate 2.0.4
- http 0.13.5
- okhttp 2.5.0
- Samsung Galaxy S22
- Android 13
- Simple HTTP Server
- Hosted by the device itself to avoid network latency impact
- Using default settings
HttpClient (Flutter)
The HTTP client from dart:io lib.
Important note: all other Flutter HTTP clients listed in this document depend on this one.
dio (Flutter)
A powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, Timeout etc.
http (Flutter)
A composable, Future-based library for making HTTP requests.
This package contains a set of high-level functions and classes that make it easy to consume HTTP resources. It's multi-platform, and supports mobile, desktop, and the browser.
A solution made just for this performance test. It uses a platform channel that uses okhttp to send requests. Each request uses a single thread from the ExecutorService. (Android doesn't allow to make HTTP request in the main thread).
dio Isolate (Flutter)
A solution made just for this performance test. It opens an isolate to perform each HTTP request with dio.
dio Isolate Service (Flutter)
A solution made just for this performance test. It opens an isolate service that is re-used for all HTTP requests. The requests are made using a single instance of dio.
There is a message exchange with the isolate using ReceivePort.
A button from a Flutter screen is pressed to start 1000 HTTP requests that are sent one at a time.
A time of 500 milliseconds is awaited before each request start. The idea of the delay is to simulate casual requests.
The time for the HTTP request is measured in microseconds and stored in an array.
Same as Light scenario, but while the execution happens, a Timer increments a counter in the screen after each 200 milliseconds. The counter increment behavior simulates things happening on Flutter while the requests are being made.
- All the Flutter's HTTP clients perform better than the native's one on the light scenario when not using isolates.
- The native has the best performance on the heavy scenario.
- Considering just Flutter HTTP clients and no isolates, the best to the worst performance order is: HttpClient -> http -> dio. That can be correlated to the amount of features these libs have.
- We can assume the native performs better on the heavy scenario because it has one extra thread to process the HTTP requests.
- The same behavior of handling well the heavy scenario on native can be observed when using isolates. That happens because isolates also use another thread.
- As dioIsolate needs to create a new isolate and a new dio client for each request, it has the worst performance of all.
Despite dio has the worst performance compared to the other Flutter's clients, it adds lots of features and improves the development experience. Using a simpler HTTP client but adding similar features would make them perform closer to dio.
The native solution could look a good way to go, but on this case, it is necessary to implement and maintain additional logic on native's side.
The dioIsolateService solution could look a good way to go, but as isolates don't share memory with the main thread, an extra effort is required to make everything work properly.
To compare what is happening on light and heavy scenarios, an extra analysis using dio and 20 HTTP requests was made.
Flutter Dev Tools was used to extract what is happening in the thread where the HTTP connections are made.
The chart bellow shows how the thread is busy on heavy scenario compared to the light one.