Azure CDN Performance with Sitecore

Recently I had to investigate a performance issue problem where images from Sitecore through an Azure CDN were being delivered very slowly. Very small images of 7kb in size were taking 500ms – 1.5s and it was causing the website to perform very poorly.

This turned out to be purely more than just a Sitecore issue and this blog article discusses some of the problems and issues which you are likely to come across when dealing with a content delivery network.

Hit or Miss

Content Delivery Networks generally have a concept of hit and miss whereby the hit delivers the content directly to the user and a miss returns to the origin. With an Azure CDN it is possible to identify whether it is a hit or a miss by looking at the response headers.

The response header x-cache: HIT is added to the response header if the CDN has achieved a HIT but if this is missing then it has gone back the origin and there will be no similar MISS identifier header. These are easily visible through the network tools in Chrome

One thing to note about this header is that it is not part of the HTTP Header standards which is why it has the x prefix

When having issues with any CDN vendor one of the best methods to receive support is to provide a HAR file which provides all of the diagnostic data. This can be generated in Chrome by when using the Network tab. Once the traffic has loaded on the page right click and select Save all as HAR with content which will generate a JSON file.

If you want to view this data in a useful format to analyse the problems, then there is a great tool provided at http://www.softwareishard.com/har/viewer/

Pop Locations

Content delivery networks depend on having point-of-presence locations in your near vicinity. They also require having a connection with your ISP and if they do not then your ISP will use the next pop location. Each provider varies so it is good to find out from a possible vendor what pop locations they offer.

https://docs.microsoft.com/en-us/azure/cdn/cdn-pop-locations

Query-string Caching

Each unique query string has its own cache key which is stored within the CDN. This cache key is then replicated through the various geographical locations using by the content delivery network provider. By adding query string keys, you are adding more variation and complexity this is a very common cause of why items respond with a miss. Reducing this complexity will definitely lead to a better hit rate.

https://www.site.com/-/media/image.ashx?w=100&hash=DAFET01AIF10AR233FTYKFD456G

Content can obviously change quite frequently on a Sitecore website and updated images will require purging. There are two ways around this:

  • Custom Media Provider

Compression

Most IIS based websites now have Dynamic Compression enabled which will allow the website to server to serve files using gzip compression. Unfortunately, even if this is enabled this won’t be replicated on the CDN and also needs to be configured there. Unfortunately the compression will only work for items which are cacheable so you will notice that pages do show as using gzip compression

This can be achieved in the CDN settings under Settings > Compression and it gives you the ability to specify the file types which you actually want to compress.

https://docs.microsoft.com/en-us/azure/cdn/cdn-improve-performance

https://docs.microsoft.com/en-us/iis/configuration/system.webserver/httpcompression/

Image Uncacheable

Dependent on the provider you can analyse the status of the CDN Cache to a certain degree. Through the Supplemental Management Portal in the Azure Portal you can find out whether images are being cached as expected.

Using a Azure CDN Verizon account this can be located under Analytics > Edge Performance Analytics > Http Large Object > CacheStatusUncacheable. This will list out all of the items which are not cached on your website. The list itself will generally consist of  popular pages and items that may not require caching.

The default setting in Sitecore for caching images is set to private but CDN’s require it to be public. Public marks the response as cacheable where as private means that the cache is specific to one user/instance. When using private this will cause traffic to route via the CDN and return to the origin.

Cache-Control: private, max-age=604800

By default the cache-control setting in Sitecore.config is set to private. This can be easily changed in the Sitecore configuration using a simple patch file

<?xml version="1.0" encoding="UTF-8"?>
<sitecore xmlns:p="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:s="http://www.sitecore.net/xmlconfig/set/">
   <settings>
      <setting name="MediaResponse.Cacheability" s:value="public" />
   </settings>
</sitecore>

External Links

https://briancaos.wordpress.com/tag/mediaresponse-cacheability/

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching

https://docs.microsoft.com/en-us/azure/cdn/cdn-manage-expiration-of-cloud-service-content

Leave a Reply

Your email address will not be published. Required fields are marked *