Table of content
    1. 1. Setup environment & create the project
    2. 2. Test performance load default
    3. 3. Test performance with cache HTTP headers
    4. 4. Summary

* Cache Type: Cache client, CDN, caching in memory browser of end-user....

* Data Cache: Only static files, such as images, css, js.

* Useful case: From second revisit page.

Okay, to test static files cache-control using HTTP Headers in Asp.net Core I will create an example with 50 big images to see how the loading page time from the second request.

1. Setup environment & create the project

- Visual studio 2019

- Asp.Net Core 2.0, 2.1, 2.2, 3.0.3.1. In this article, I’m using version 3.1 to make an example.

Okay, now we open vs2019 and create a web application project to make an example now.

Step 1. Open vs2019 -> click Create a new project option on the right side.

Step 2. Select ASP.NET Core Web Application project type and click Next button.

Step 3. Enter the project name and click Create button.

Step 4. Select the project type is Web Application and click Create button.

2. Test performance load default

Now I will display 50 big images on a web page and test the performance of it from the first time and second time. 

This is my web page with 50 images:

ASP.NET Core: Adding cache static file using HTTP headers

By default, Cache-control can not add to the header response of a static file. When you finish the created project you can open StartUp.cs file and inside of Configure() method  and you will see middleware UseStaticFiles() add default to your project. 

 

- UseStaticFiles(): Help enables static file serving for the current request path. By default, the root static folder is wwwroot. So all static files you need put inside this folder.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  ……..
  app.UseStaticFiles();
  ……..
}

Now, we run applications and check web page time load with developer tools.

ASP.NET Core: Adding cache static file using HTTP headers

With default mode, load time is 1.17s with 59 requests to transfer 5.3MB data from server to client. I think it is too heavy and too slow. We can check the header response of an image you can see as below: 

accept-ranges: bytes
content-length: 42182
content-type: image/jpeg
date: Fri, 25 Sep 2020 16:37:29 GMT
etag: "1d69283ade7ff46"
last-modified: Thu, 24 Sep 2020 15:02:11 GMT
server: Microsoft-IIS/10.0
status: 200
x-powered-by: ASP.NET

You can see it can not be cached here.

3. Test performance with cache HTTP headers

To enable Cache-Control in Asp.Net Core for all static files we need to add cache-control to the header response of each static file.

Step 1. Enable cookie policy.

Open StartUp.cs file, inside the method Configure() we need to register the middleware cookie policy as below:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  -------
  app.UseCookiePolicy();
  -------
}

Step 2. Add Cache-Control to the HTTP header of the static file.

To add cache-control to the response header of each response static file we need to custom middleware UseStaticFiles() as below:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    --------------
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = context =>
        {
            // add time expires header
            const int durationInSeconds = (60 * 60 * 24) * 365; // Expires time. I set to 1 year
            context.Context.Response.Headers["Cache-Control"] =
                "public,max-age=" + durationInSeconds;
        }
    });
    --------------
}
 

In that :

Max-age :

Time expires cache, after this total second that resource will be called to the server to reload again the resource file.

Cache-Control: Public 

The public response directive indicates that a resource can be cached by any cache.
Use this option when resources never or less update such as js, css, image.

Cache-Control: Private

This option indicates that all static files will be stored in the local memory of the end user.

Cache-Control: No-Cache

The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it, therefore, you cannot use no-cache in-conjunction with immutable. If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response.

Cache-Control: No-Store

This option tells that browsers aren’t allowed to cache a response and must pull it from the server each time it’s requested. This setting is usually used for sensitive data, such as personal banking details.

And this is the result from the second request:

ASP.NET Core: Adding cache static file using HTTP headers

 

Wow, still 59 requests, 5.5MB resources but now we only have 34.2kb transferred instead of 5.3MB and the time load is 442ms instead of 1.17s as above. It is too fast and load page faster than ~ 3 times.

And this is the response header of a static file with cache control:

ASP.NET Core: Adding cache static file using HTTP headers

OTHER INFORMATION
When you use cache-control I think you should also understand about Etag, If-Match and If-None-Match header. Three of these options will help optimize better cache static files.

ETag – A response header that identifies the version of served content according to a token – a string of characters in quotes, e.g., "0987656af37gfe98-ttgv4" – that changes after a resource is modified. If a token is unchanged before a request is made, the browser continues to use its local version.

You can read more them from Mozilla 

4. Summary

In this article, I guide how to enable Asp.Net Core cache control header? and see why it is important? This is a big point to increase Google page speed’s point. Cache-control headers help increase user experience better than when visiting a site. 

You can download the source for reference here.

Happy code!!!