Tuesday, December 8, 2015

Cache buster for IIS



Optimizing a web site includes specifying a long expiration headers.If we do this we need to make sure we have a cache buster


Drawback : If there is a change in the cached files the browser would not take the latest version.


Solution

1) We can specify query string parameter as cache buster

       
  <link href="/Content/release/core.min.css?v=1.2" rel="stylesheet"/>
  
    
However some proxy do not cache any URL with query string "?"  

2)  The best approach is to write cache buster logic as shown below

Steps involved
  • Specify expiration header based on the need
<staticContent >
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00"/>
 </staticContent>
  • Write a helper class to get the timestamp of the file and it as a path
using System;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;

namespace SelfService.Loma.org.Utilities
{
    public class CacheBuster
    {
        public static string Tag(string rootRelativePath)
        {
            if (HttpRuntime.Cache[rootRelativePath] == null)
            {
                string absolute = HostingEnvironment.MapPath("~" + rootRelativePath);

                DateTime date = File.GetLastWriteTime(absolute);
                int index = rootRelativePath.LastIndexOf('/');

                string result = rootRelativePath.Insert(index, "/v-" + date.Ticks);
                HttpRuntime.Cache.Insert(rootRelativePath, result, new CacheDependency(absolute));
            }

            return HttpRuntime.Cache[rootRelativePath] as string;
        }
    }
}
  • Change the reference path 
 <link href="@CacheBuster.Tag("/Content/release/core.min.css")" rel="stylesheet" />

  • Specify url rewrite in web.config file (This url rewrite is for IIS . It would make sure that the fake path would be replaced by actual path)
<system.webServer>
    <rewrite>
        <rules>
          <rule name="CacheBuster">
            <match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
            <action type="Rewrite" url="{R:1}/{R:3}" />
          </rule>
        </rules>
    </rewrite>
  </system.webServer>

No comments:

Post a Comment