Increase Performance by Using Cache-Control Header in Blob Storage





5.00/5 (2 votes)
Increase Performance by Using Cache-Control Header in Blob Storage
Caching has always been an important part of a good application design and performance optimization. Fetching something over the network is both slow and expensive; large responses require many round-trips between the client and server, which delays when they are available and can be processed by the browser, and also incurs data costs for the visitor. As a result, the ability to cache and reuse previously fetched resources is a critical aspect of optimizing for performance.
In this post, we'll see how we can optimize performance by using "Cache-Control
" header in Azure Blob Storage. For this, I assume you have an Azure subscription and a Storage account.
Let's see step by step how we can add "Cache-Control
" header to a block blob.
In this example, we'll upload an image to Azure Blob Storage from a simple ASP.NET application.
- Go to Azure Portal -> Storage->Containers and create a new container. You can select the access control option "
Public Blob
". In real life, you would not like to select this option always, but let's have it for this post. - Open Visual Studio and create an ASP.NET application. On Default.aspx, let's have a
Button
and aFileUpload
control. On click of the button, we'll upload the selected file to Blob Storage. - The code for Button click event handler looks like below:
protected void btnUpload_Click(object sender, EventArgs e) { if (!file1.HasFile) return; var storageConStr = CloudConfigurationManager.GetSetting("StorageConStr"); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConStr); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer blobContainer = blobClient.GetContainerReference("container1"); blobContainer.CreateIfNotExists(BlobContainerPublicAccessType.Blob); CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(file1.FileName); //Add Cache-Control header blockBlob.Properties.CacheControl = "public,max-age="+60; blockBlob.UploadFromStream(file1.FileContent); }
In the above snippet, see the assignment:
blockBlob.Properties.CacheControl = "public,max-age="+60.
This is to specify that the response is cacheable by clients and shared (proxy) caches.
- Now run the application, choose a file and store it in blob storage.
- Now add an HTML image element on the page and assign the blob url to
src
attribute.<img src="https://authority.blob.core.windows.net/container1/list_red_car.png" />
- Now run the application, press F12 to open the developer console on browser and go to network tab. Find out the request to your blob url and have a look at the Response headers.
Have a look at the response headers marked with red circles.
- "
Cache-Control
" header is to specify that the browser can cache the response for the specified time. - "
Etag
" is one of several mechanisms that HTTP provides for web cache validation, which allows a client to make conditional requests.This allows caches to be more efficient, and saves bandwidth, as a web server does not need to send a full response if the content has not changed. You can learn more aboutEtag
s here.
- "
- Now refresh the browser page and have a look at the blob url request in the network tab of developer console. You will see something similar to the below image.
Points of Interest
- Response Status Code 304 (Not Modified): The condition specified using HTTP conditional header(s) is not met.
The above statement describes pretty much everything about Http Status Code 304. It says that whatever condition was specified in the
Request
, was not met. Now, let's have a look at point 2 below to understand exactly what "condition" was specified in the Request. - In-None-Match Request Header: In the above screenshot, you can see the header is underlined in red. This is the condition specified in the request!! You can see, this header actually contains the same "
Etag
" which was sent by the server in step 6 above.By including the "
Etag
" in the "If-None-Match
" header, the browser is actually requesting the server that, if the "Etag
" is still the same as the one included in the header, there is no need to download the resource from storage, instead return Status Code 304 (Not Modified). The browser will now get the file from its own cache.
Note: The Etag on server will change only when the resource is modified.
In this post, we've seen how browser does efficient caching using different headers (like Cache-Control
Response Header, If-None-Match
Request Header) and Etag
.
In my next post, I'll show how we can achieve efficient caching using the same headers and Etag
in .NET using C#.