Using minified CSS and JavaScript files everywhere in SharePoint 2010

Find out how to leverage the extensibility capabilities of the SharePoint 2010 platform and support using minified CSS and JavaScript files everywhere.
Page Content


In my previous post I showed you how you can automate minifying JavaScript and CSS files in Visual Studio 2010. As I also mentioned, SharePoint has limited support for using minified files. But just because something is not available out of the box doesn’t mean it’s not possible. Find out how to leverage the extensibility capabilities of the SharePoint 2010 platform and support using minified CSS and JavaScript files everywhere.

Minified files and the ScriptLink control

Using minified files is a great and easy technique for optimizing your SharePoint solution for performance. Out-of-the-box SharePoint 2010 provides the ScriptLink control which allows you to automatically switch between raw and minified versions of your files. However, it has two flaws. First of all it supports only JavaScript files and just as you can minify JavaScript files, you can also minify your CSS files. Another thing that you have to keep in mind, if you want to use the standard ScriptLink control with minified files, is that it works only for JavaScript files deployed to the LAYOUTS folder on the file system.

Using minified files everywhere

If you want to use minified CSS and JavaScript files everywhere you will need a solution other than the standard ScriptLink control. One solution that you could consider is creating a custom control that you would add to your Master Page and which would automatically switch between the raw and minified version of the asset file depending on the mode in which the Web Application is working. Such control could look as follows:

001 using System; 
002 using System.IO; 
003 using System.Web; 
004 using System.Web.UI; 
005 using Microsoft.SharePoint.Utilities; 
007 namespace Mavention.SharePoint.Controls { 
008     public enum AssetType { 
009         CSS, 
010         JavaScript, 
011         Other 
014     public class AssetLinkControl : Control { 
015         public string Href { get; set; } 
016         public bool WithDebug { get; set; } 
018         protected override void Render(HtmlTextWriter writer) { 
019             if (!String.IsNullOrEmpty(Href)) { 
020                 AssetType assetType = AssetType.Other; 
021                 string href = GetAssetUrl(Href, WithDebug, out assetType); 
023                 switch (assetType) { 
024                     case AssetType.CSS: 
025                         RenderCssLink(href, writer); 
026                         break
027                     case AssetType.JavaScript: 
028                         RenderJsLink(href, writer); 
029                         break
034         public static string GetAssetUrl(string url, bool withDebug, out AssetType assetType) { 
035             string assetUrl = url; 
036             assetType = AssetType.Other; 
038             if (!String.IsNullOrEmpty(assetUrl)) { 
039                 assetUrl = SPUtility.GetServerRelativeUrlFromPrefixedUrl(assetUrl); 
040                 assetType = GetAssetType(assetUrl); 
042                 if (withDebug && HttpContext.Current.IsDebuggingEnabled) { 
043                     assetUrl = GetDebugUrl(assetUrl, assetType); 
047             return assetUrl; 
050         private static AssetType GetAssetType(string url) { 
051             AssetType assetType = AssetType.Other; 
053             if (!String.IsNullOrEmpty(url)) { 
054                 string extension = Path.GetExtension(url); 
055                 switch (extension) { 
056                     case ".css"
057                         assetType = AssetType.CSS; 
058                         break
059                     case ".js"
060                         assetType = AssetType.JavaScript; 
061                         break
065             return assetType; 
068         private static string GetDebugUrl(string url, AssetType assetType) { 
069             string debugUrl = url; 
071             if (!String.IsNullOrEmpty(debugUrl)) { 
072                 string extension = Path.GetExtension(debugUrl); 
073                 switch (assetType) { 
074                     case AssetType.CSS: 
075                         extension = ".css"
076                         break
077                     case AssetType.JavaScript: 
078                         extension = ".js"
079                         break
082                 debugUrl = String.Concat(debugUrl.Replace(extension, String.Format(".debug{0}", extension))); 
085             return debugUrl; 
088         private void RenderJsLink(string href, HtmlTextWriter writer) { 
089             writer.AddAttribute(HtmlTextWriterAttribute.Src, href); 
090             writer.RenderBeginTag(HtmlTextWriterTag.Script); 
091             writer.RenderEndTag(); 
094         private void RenderCssLink(string href, HtmlTextWriter writer) { 
095             writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet"); 
096             writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css"); 
097             writer.AddAttribute(HtmlTextWriterAttribute.Href, href); 
098             writer.RenderBeginTag(HtmlTextWriterTag.Link); 
099             writer.RenderEndTag(); 
102 }

How it works

We start with retrieving the URL of the asset (line 21). To provide flexibility when defining URLs we first translate the URL to a server-relative URL by parsing tokens if applicable (line 39). Next we get the type of the asset that we are working with (line 40). While we could create two separate controls: one for CSS files and one for JavaScript files, in this sample we use one control for both types. The last step is to check whether the asset link points to an asset that is provided in two versions (raw and minified) and if the Web Application is in debug mode (line 42).

Using the WithDebug property allows us to use the AssetLinkControl both for referencing files that have already been minified (like the jQuery library) as well as files that we have created ourselves and that are available both as raw and minified files.

If the Web Application is in debug mode we convert the asset link to point to the debug version of the asset (line 43). Finally we return the URL and render it depending on the asset type (lines 23-30).

Using the AssetLinkControl

The AssetLinkControl can be used the best for declaratively registering assets in the Master Page and Page Layouts. To register an asset, all you have to do is to include the following snippet:

1 <Mavention:AssetLinkControl Href="~SiteCollection/Style Library/mavention/css/mavention.css" WithDebug="true" runat="server" />

Depending on the mode in which your Web Application is running, this control will either point to the minified or the debug version of the CSS file.

What the AssetLinkControl is not

Although the AssetLinkControl provides you with great flexibility, it is by no means a replacement for dynamically registering JavaScript or CSS files. The standard SharePoint 2010 CssRegistration and ScriptLink controls provide much more flexibility allowing you to determine how and when your assets should be loaded. Whenever you need to register a CSS or a JavaScript file on runtime you should use those standard controls instead. The great thing about how the AssetLinkControl is built, is that you can use its GetAssetUrl method to build a URL to your asset and then pass it to the standard SharePoint controls. This approach allows you to extend the standard functionality of the SharePoint platform with additional flexibility and optimization for performance.


1 Comment (+add yours?)

  1. MD
    Jul 21, 2015 @ 17:55:27

    Generally I don’t read article on blogs, however I would like to
    say that this write-up very forced me to try and do so!
    Your writing taste has been amazed me. Thank you, quite great post.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: