Skip to content

[HttpClientFactory] Add support for client-side cache-control #1384

@dotMorten

Description

@dotMorten

In .NET Framework it was possible to specify that web requests should use the shared browser cache by setting:
myWebRequestHandler.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Default);

This allows repeated web requests to either be pulled from the local browser cache (if not expired) or do much faster ETag 304 requests/response. This is really really useful for client apps that frequently check for status updates in a resource, image tile requests etc, and can reduce the network overhead tremendously.

For example I made a (very) quick and dirty cache implementation showing a 33x perf increase on repeated requests when implementing cache-control max-age and/or etag:

Method Mean Error StdDev Median Ratio Gen 0 Gen 1 Gen 2 Allocated
UseSocketsHttpHandler 48.710 ms 0.4979 ms 0.4414 ms 48.694 ms 1.00 - - - 243.08 KB
UseHttpClientHandler 47.781 ms 0.5331 ms 0.4451 ms 47.884 ms 0.98 - - - 242.25 KB
UseCacheHttpHandler 1.252 ms 0.0665 ms 0.1907 ms 1.199 ms 0.03 - - - 247.48 KB

Test was done on an above-average high-speed internet connection. Effect would of course be A LOT bigger on slower networks.

However building a proper caching mechanism that deals with shared vs private cache, cache expiration, pruning (when it grows too large), lock contention for parallel requests, re-using the shared OS browser cache (like what wininet offers), etc is no trivial task. And even so, not having this at a platform level means there's no way to make caching possible with 3rd party libraries, because it currently has to be done manually at a very low level of the request.

/CC @karelz

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions