Open eerhardt opened 2 years ago
Tagging subscribers to this area: @dotnet/ncl See info in area-owners.md if you want to be subscribed.
Author: | eerhardt |
---|---|
Assignees: | - |
Labels: | `tenet-performance`, `area-Extensions-HttpClientFactory` |
Milestone: | - |
For the podcast app, should we maybe go with something like:
services.TryAddSingleton<HttpClient>(sp => new HttpClient());
And use 1 instance of HttpClient
for the entire app?
That's similar to what I did: https://github.com/eerhardt/dotnet-podcasts/commit/e0849b2f9444cfc09bab6d3b62ecf2b637946f18
I just didn't use DI to inject an HttpClient. Instead, I just made a static variable in ShowsService
.
One issue with injecting an HttpClient is if you are connecting to multiple endpoints. It is easier to set the "BaseAddress", or headers, on different instances of HttpClient.
Yes, I would say it's quite a heavy overhead for the mobile usages - which might not be needed at all. The factory means to solve two problems - socket exhaustion (that can be solved by a static/singleton HttpClient) and not losing DNS changes. I am not sure whether the second problem even exists for mobile usages? Given it's not SocketsHttpHandler that is used there.
This issue has been marked needs-author-action
and may be missing some important information.
Socket exhaustion definitely seems like something server scenarios would run into. If mobile app is making enough web requests to hit that problem, I would probably recommend "don't do that". Even if a mobile app was downloading lots of files, they should probably limit to 4 (or some number) of concurrent connections
The IHttpClientFactory isn't just about socket exhaustion and dns changes, it's about a DI friendly way to configure and pass around the http client. It just so happens that startup time is affected because of IL emit. I'm pretty sure we could come up with something more mobile friendly configuration wise, but I haven't thought through how to work around/fix the startup performance problems.
It just so happens that startup time is affected because of IL emit
The Logging in Microsoft.Extensions.Http also seems to be adding a decent amount of overhead
Hmmm, maybe worth making that opt-in.
Description
In profiling the .NET Podcasts application startup time on an Android Pixel 5a, I'm seeing its usage of a named HttpClient using
builder.Services.AddHttpClient<ShowsService>(client => {})
as taking up 5% of the startup cost of the app.Configuration
6.0
Android 12
ARM64
Google Pixel 5a
Regression?
No
Data
Using the startup profiling script at https://github.com/jonathanpeppers/maui-profiling#faq, I'm getting the following results:
(using a full AOT of the app, so to eliminate any JIT time)
Startup time with AddHttpClient
Average(ms): 838.2 Average(ms): 832.4 Average(ms): 835.2
Startup time with just creating a shared HttpClient without DI
Average(ms): 795.5 Average(ms): 799.8 Average(ms): 797.9
Analysis
dotnet-podcasts.speedscope.zip
A big chunk of that time is due to calling ActivatorUtilities.CreateFactory, which uses System.Linq.Expressions and IL Ref.Emit.
Discussion
I wonder if using Microsoft.Extensions.Http on a mobile application is recommended at all. Or if a mobile app should just be following the guidance we give in our docs:
@davidfowl @jonathanpeppers @dotnet/ncl