ASP.NET 4.5 Bundling and Minification Support

If you’re serious about web development, you strive for a fast website.  Nothing beats the feeling of sitting back and viewing a great website that’s fast.  Speed matters.  Your customers expect it.  If you don’t think they do, you’re living in a different world to mine.  With a growing trend of consumers buying online in 2011, developers have to cope with the extra devices customers will use to browse your website.

There are many ways to increase the performance of a website, but the way with the biggest impact by far is to decrease the number of HTTP requests.  Every time you reference an image, CSS file, JavaScript file, video, audio or a flash file, that adds an extra HTTP request.  That is time that could be used elsewhere, such as taking customer orders!

One way of reducing the number of HTTP requests is to combine the files.  If you have three style sheets sitting in your web page, that’s three separate HTTP requests.  Combining them into one file means there’s only one HTTP request.

You can take this one step further and add minification to this process.  Minification is the process of stripping out all of the white-space and comments from your CSS and JavaScript files.

If you’re familiar with ASP.NET, bundling and minification was always a job for your build process.  With the advent of Visual Studio 2011 and ASP.NET 4.5, Microsoft has added bundling and minification out of the box, which in my opinion has been long overdue.  This process happens at run-time and is available to ASP.NET WinForms, MVC and Web Pages.

Installation

Before starting any development, you’ll need to install ASP.NET 4.5.  The simplest way to do this is via the Web Platform Installer.  All of the ASP.NET 4.5 articles I’m authoring are developed in Visual Studio 2011 Developer Preview. Below are the links to get started.

Why Do This?

The answer is simple; to reduce the number of HTTP requests that go between the client and server.  The result is a faster website.  By default when you create a new MVC 4 website, the following JavaScript files are loaded into the page.

<script type="text/javascript" src="../../Scripts/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery-ui-1.8.11.js"></script>
<script type="text/javascript" src="../../Scripts/modernizr-2.0.6-development-only.js"></script>
<script type="text/javascript" src="../../Scripts/AjaxLogin.js"></script>

Looking at this through Chrome you can see the 4 separate HTTP requests.

We can do better that that! After you bundle it, you’ll see one request.

Where’s the Magic?

The magic happens at runtime in ASP.NET 4.5.  Instead of referencing each JavaScript file separately, you can replace them all with this:

<script src="scripts/js"></script>

And you can also bundle and minify your CSS files too by adding this line of code:

<link href="content/css" rel="stylesheet" />

This is assuming you have your JavaScript files in a folder called scripts, and your style sheets are in a folder called content.  This is configurable, of course – as you’ll soon see.

Before this will work, you need to add one line of code to the global.asax file in the Application Start event.

Bundle.Bundles.EnableDefaultBundles();

The need for this line of code will be removed when ASP.NET 4.5 is released.  When the website is running, if ASP.NET encounters either of these tags, it will automatically bundle and minify each file in the given folder and send back a single HTTP response for the JavaScript file and a single response for the CSS.  Out of the box you don’t need to do anything else.  This is a welcome feature.

By default, when the files are bundled by ASP.NET they are in alphabetical order.  If there are known libraries such as jQuery, jQuery UI and Dojo, they are loaded first.  For the CSS files, they are also bundled in alphabetical order.  The results can be seen in the image below.

Custom Rules

If the default bundling rules don’t give you the control that you need, you can always create your own bundling rules.  A common reason for doing this is to group common libraries.  There aren’t too many occasions when you need to bundle your entire JavaScript or CSS files into the one file.  To create a custom rule you create a new Bundle object.  Then you add files individually or an entire directory.

var jSBundle = new Bundle("~/CustomJs", typeof(JsMinify));
jSBundle.AddFile("~/Scripts/CustomFunction.js");
jSBundle.AddFile("~/Scripts/jquery-1.4.1-vsdoc.js");
jSBundle.AddFile("~/Scripts/jquery-1.4.1.js");
jSBundle.AddFile("~/Scripts/JSONCreate.js");

Notice the type JsMinify above?  That’s the default object that bundles and minifies the JavaScript files.  For CSS, you use CssMinify like the example below.

var cssBundle = new Bundle("~/CustomCss", typeof(CssMinify));
cssBundle.AddFile("~/Content/Collection.css");
cssBundle.AddFile("~/Content/GlobalSupport.css");
cssBundle.AddFile("~/Content/MasterStyle.css");
cssBundle.AddFile("~/Styles/MenuStyle.css");

To reference these custom rules, you put the name of each bundle in your HTML.

<script src="CustomJs"></script> or <link href="CustomCss" rel="stylesheet" />

Custom Processing

If you want total control, you can override the default CSS and JavaScript bundling support and replace it with a custom process.  An easy way to do this is to create a class that implements the IBundleTransform interface.  The following example is trivial but it demonstrates how to do this.  The example inserts a company copyright into each JavaScript files and sets the default cache for the file.

public class AddCopyrightToFiles : IBundleTransform
{
    public void Process(BundleResponse bundle)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("// Copyright your company");
        sb.AppendLine(bundle.Content);
        bundle.Content = sb.ToString();
        bundle.Cacheability = HttpCacheability.ServerAndNoCache;
    }
}

And to use this custom process, create a new Bundle and reference the custom class.

BundleTable.Bundles.EnableDefaultBundles();
Bundle customBundle = new Bundle("~/CustomBundle", typeof(AddCopyrightToFiles));
customBundle.AddFile("~/Scripts/CustomTypes.js");
BundleTable.Bundles.Add(customBundle);

And in the HTML, just reference the bundle by its name.

<script src="CustomBundle"></script>

Unbundle JavaScript Files

It’s worth noting that there are services that will unbundle your files, or beautify them.  The one I love to use is jsbeautifier.  This flattens the file.  One of the biggest drawbacks of bundling and minification is readability.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Ed Charbeneau

    Good info.
    “Before starting any development, you’ll need to install ASP.NET 4.5.” Actually, you can start using bundling and minification with your current install of asp.net. Microsoft.Web.Optimization is the library that does the “Magic” for you and it’s currently available as a nuget package.
    http://www.nuget.org/packages/Microsoft.Web.Optimization
    Go one step further and get both responsive design and minification by downloading this package.
    http://www.nuget.org/packages/Zurb_Foundation_MVC3

  • Malcolm Sheridan

    @Ed,

    Yes you can download it as a separate package. I didn’t mention it because I was writing about out of the box functionality in ASP.NET 4.5.

    Thanks for pointing it out though.

    Cheers

  • http://www.brickred.com BrickRed

    Very Informative!!

  • http://www.logicspeak.com Gordon Patrick

    I noticed in one of your images that a web resource was not included in the bundling. I would assume the same would be true for script resource files? Can you provide some information about including these files that are embedded in assemblies. This would greatly help in the loading of the AjaxControlToolkit’s HtmlEditor control!!