3

I want my JavaScript that's referenced through <script> tags, my css, and various graphic files to be cached on the user browser for a given release of my site. However, when I release an update to a file, I would like to ensure that the new content (Javascript, css, graphics, etc) will be updated on the user's machine.

In researching this problem, I've come across a number of possible solutions:

  1. Adjust http headers for things like cache control and expires
  2. Append a unique querystring to each resource request
  3. Include a version number in the path (or filename) of the resource being requested

My concern with option 1 (other than not knowing how to implement it for some content types) is that if there's an intermediate proxy between the browser and IIS, then the intermediate proxy may not respect the http headers, and the content would be cached between the browser and the proxy.

My concern with option 2 is two fold. For one, if I just use a random number or timestamp, then the browser will request a new resource every time, bypassing the local cache even when the content hasn't changed (when not between releases). A workaround to this problem is to use the timestamp of the resource file or a hash of the file; this would change only when a new release occurs. However, this lead to my second concern: I understand that some web proxies never cache anything with a query string, by default (http://stackoverflow.com/questions/5541340/how-can-i-prevent-javascript-caching-querystring-approach-isnt-working). While this is likely customizable, I wouldn't want to rely on the administrator changing a setting from the default, in order to get the performance benefit of caching.

Option 3 seems like the best choice, but I don't know how to implement it in a practical manner, for ASP .NET MVC (currently using ASP .NET MVC 3). By hand, I could go into every file that links to a graphic, css or external javascript file and change the path to include a different version number for each release, but clearly this is tedious and error prone.

My questions then are:

1) Are there any other strategies to avoid caching (for a given release) that I should consider and

2) assuming I use option 3 (including a version number in the path of the resource), how I can I achieve this in an ASP .NET MVC application, in a way that is realistic to maintain?

Thanks,

Notre

Notre
  • 1,093
  • 3
  • 13
  • 26

2 Answers2

2

The idea is whenever the version of the js, css files changes you have to change the URL from the server so the browser request for the new version.

Please refer the answer of @Kip in this thread that clearly describes about this. Though the answer is in php it can be implemented in asp.net mvc itself.

If you are using the new bundling/minification feature of ASP.NET MVC 4 I think the versioning be taken care automatically by it(not sure though).

Community
  • 1
  • 1
VJAI
  • 32,167
  • 23
  • 102
  • 164
  • +1 We bundle and append the build number to requests to that asset bundle, so as to avoid the inevitable "clear your browser cache" phone calls when we upgrade. – moribvndvs Jun 20 '12 at 05:35
  • Thanks Mark for sharing the thread with @Kip's answer. This looks like exactly the type of thing I want, and I'll look at prototyping it. Yes, you're right re: bundling/minificiation of ASP .NET MVC 4 -- I found on a diferent thread that it is handled automatically. (It does use the query string approach, which I'm not quite as happy about for reasons note above). Currently, we're still on ASP .NET MVC 3 so I can't adopt that solution yet. – Notre Jun 21 '12 at 00:18
1

Http caching is done in 2 ways. By validation mechanism and by expiration mechanism.

For Expiration mechanism you could use expires on header(but this is good for static resource which you know would never change).

For validation mechanism and conditional get ETags are used which seems to be a perfect case for your problem.

Anand
  • 14,545
  • 8
  • 32
  • 44
  • Hi Anad, can you please expand on validation mechanism and conditional ETags? Maybe with a link or something? I'm not sure what all that means, nor how to apply it. Thanks! – Notre Jun 20 '12 at 20:28
  • Hi, for Etags and Cache control please refer this article http://developer.yahoo.com/performance/rules.html For how to implement in MVC. Please refer this article http://stackoverflow.com/questions/6642815/create-etag-filler-in-asp-net-mvc – Anand Jun 21 '12 at 07:05
  • Thanks for the information. That Yahoo performance document was brilliant! After reading the section on ETags in it, I believe this is not the way to go, for the reasons stated in the article. The article earlier stated "if you use a far future Expires header you have to change the component's filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component's filename, for example, yahoo_2.0.6.js." This validates my impression this is the right way to go. – Notre Jun 21 '12 at 17:20
  • what about setting ETags ? Whenever component changes, you could change the etag for your js files. – Anand Jun 22 '12 at 04:45
  • It seems like ETags can be problematic, according to the Yahoo article you provided; please see the "Configure ETag" section – Notre Jun 26 '12 at 21:57