There are different ways of implementing the caching.
1.
At the server, where you store data in-memory using
the ASP.Net Cache / Application classes.
2.
In the client (Browser). This definitely gives
more advantage in terms of performance.
This article describes in detail about the second type of
caching.
What are the
resources that can be cached?
Static resources like html, scripts - js, style sheets – css,
images – gif, jpg etc
Ex: http://www.domain.com/images/banner.jpg
Ex: http://www.domain.com/images/banner.jpg
Dynamic resources which are REST based urls - if you think that these resources don’t
change their data very frequently then they can be a good candidate for
caching.
Ex:
What do we intend to
save by caching on the browser?
Loading the server to fetch the data and pass it across
Even making an http request to the server. There are other
ways to save the number of requests to server by using minification process.
Where we can merge several js/css files into single file. You can read my
previous articles to know more about it.
Implementing Caching
This is simple by adding Expires Header (when you know
exactly when to expire) to the IIS. http://technet.microsoft.com/en-us/library/cc770661(WS.10).aspx
You can also use the Max Age header when you are not sure of
the number days you need to cache the resource. The above link describes for both.
Challenges
Finding the exact Expires/MaxAge becomes hard as we will not
be able to predict our bug fix cycles due to hot fixes etc.. specially in case
of smaller projects.
Solution
Two common solutions both deal with manipulating the URL:
1.
Manipulate the calls to the resource by adding a
query string. This requires to do a find a replace to all the locations where
the resource is being referenced. Ex: http://www.domain.com/app/images/banner.jpg?rev=2345
. This becomes a painful process to manipulate it every time a resource is
changed. There are very high chances that we may miss out modifying a revision
query string. This also has some minor drawbacks that some proxy servers don’t
cache urls which contain query string.
For REST
based WCF Service, add this piece of code before the response.
OutgoingWebResponseContext ctx = WebOperationContext.Current.OutgoingResponse;
ctx.Headers.Add(HttpResponseHeader.CacheControl, String.Format("public,
max-age={0}", maxAge)); //in seconds.
2.
The second more robust solution “Fingerprinting”
is to inject some kind of hash into the url. Ex: http://www.domain.com/CBUSTZqTMzNV8qFU/0.jpg
Here the part of the url before the
file name is the fingerprint or a hash generated based on the contents of the resource
being accessed. This requires that we use some mechanism like a URL Rewrite
module to do a Rewrite of requests. Ex: Search for a pattern (.*)/CBUST[A-F0-9]{32}(/.*)
and do a rewrite to {R:1}{R:2} For more information on URL Rewrite http://www.iis.net/download/urlrewrite
In your aspx files, you will reference your resources like
<script type="text/javascript" src="<%=Utilities.CacheBusterUrl("/_layouts/scripts/jquery-1.4.3.min.js"%>">script>
This will end up creating a url something like http://www.domain.com/_layouts/scripts/CBUSTZqTMzNV8qFU/jquery-1.4.3.min.js
Add this piece of code in your
Page_Load if it is a page.
if (!this.Page.IsPostBack)
{
this.DataBind();
}
If it
is a user/web control then ensure that the page that is adding this user/web
control has the above piece of code.
The
Fingerprinting method has its own limitation that any resource referenced in
.css file or being rendered from SharePoint library cannot be cached like this.
Implementation
of the CacheBuster utility is as follows.
public static
class Utilities
{
private
static Hashtable
Md5Map = Hashtable.Synchronized(new Hashtable());
public static string
CacheBusterUrl(string sourceUrl)
{
try
{
string
filesystemPath = HttpContext.Current.Server.MapPath(sourceUrl);
string
fileMD5;
lock
(Md5Map.SyncRoot)
{
if
(Md5Map.ContainsKey(filesystemPath))
{
fileMD5 =
Md5Map[filesystemPath].ToString();
}
else
{
fileMD5 = CreateHash(filesystemPath);
Md5Map.Add(filesystemPath, fileMD5);
}
}
return
BuildCacheBusterURL(sourceUrl,
fileMD5);
}
catch
(Exception ex)
{
return
sourceUrl;
}
}
}
Security Warning
Be aware that if your Web Application stores cookies then
caching resources at the proxy servers can be a security threat. So make sure
to use https whenever you decide to store cookies.
No comments:
Post a Comment