Sharepoint - How to avoid caching issue when using custom JavaScript and CSS deployed under _layouts?

SPUtility provide us a method called - MakeBrowserCacheSafeLayoutsUrl(string, boolean) and other overload methods.

Based on last modification this itself generate a MD5 hash code and append it to css or js urls. We don't have to worry about finding version numbers or generating id based on creation date, this is already handled.

I have used this in my project for handling css caching for custom css. SharePoint internally does same for OOB css which are rendered by CSSLink.

protected override void OnInit(EventArgs e)
{
        CssRegistration cssRegistration1 = new CssRegistration();        
        cssRegistration1.After = "corev4.css";
        cssRegistration1.ConditionalExpression = "IE 7";
        cssRegistration1.Name = SPUtility.MakeBrowserCacheSafeLayoutsUrl("FolderBelowLayouts/Styles/CustomCss.css", false); //will be /_layouts/15/FolderBelowLayouts/Styles/CustomCss.css?rev=...
        Controls.Add(cssRegistration1);
        base.OnInit(e);
}

and for link tags you can directly do:

<link rel="stylesheet" type="text/css" href="<%=SPUtility.MakeBrowserCacheSafeLayoutsUrl("FolderBelowLayouts/Styles/CustomCss.css", false)%>" />

Refer to: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.utilities.sputility.makebrowsercachesafelayoutsurl.aspx


The solution is, to get rid of the starting "/" in your Name values.

JS

SharePoint will automatically check, if the js file changes and will append a custom query string with a revision number, just like it does with the internal js files, if you check the source of your website. You just have to change the Name in your Scriptlink control like:

<SharePoint:ScriptLink 
    runat="server" 
    Name="scripts/company/custom.js" 
    Localizable="false"
    id="customJs" />

This will change the path to your custom.js on the website to s.th. like:

<script src="/_Layouts/scripts/company/custom.js?rev=HVORLc5FI20n7W90mjha3A%3D%3D"></script>

(If you have your JS files under _layouts/1033, you should set localizable to "true" and keep the Name path the same).

CSS

For CSS, the relative path starts under "/_layouts/1033/styles", so to get to "/_layouts" and make SharePoint take care of Cache Busting, you should change your CSSRegistration Name to the following

<SharePoint:CssRegistration runat="server" Name="../../company/custom.css" id="customCss" />

This will change the path to your custom.css on the website to s.th. like:

<link id="CssRegistration2" rel="stylesheet" type="text/css" href="/_Layouts/1033/styles/../../scripts/company/custom.css?rev=p63%2BuzTeSJc22nVGNZ5zwg%3D%3D"/>

(For CSS, I am not sure, if you can use Localizable="False")

Interesting article: http://community.rightpoint.com/blogs/viewpoint/archive/2012/02/24/cache-busting-with-the-sharepoint-cssregistration-control.aspx


Steve,

there is no clean solution for your problem. Browsers cache files by url, you can avoid caching appending in query string unique value per deployment. For example

_layouts/my_js_file.js?v=<current date> - will be refreshed from cache when day changes

_layouts/my_js_file.js?v=<GUID> - if guid is generated on every request, this file should never cache

_layouts/my_js_file.js?v=<product version> - more preferable solution, browser will update cache on every new version that was deployed

Actually, ScriptLink should take care about this, internally it has a method that appends unique id into query string based on js file content, if content changed, hash is also changed and new unique id is generated.

I recommend you to read this article about your issue.

Tags:

Javascript

Css