How to use bundling to minify css and JavaScript in MVC and Umbraco

Posted written by Paul Seal on February 25, 2016 .NET Framework

This post shows you how to set up and use bundling and minification in your MVC website. There are specific instructions on how set it up for Umbraco websites too.

What is bundling?

Bundling is a new feature in ASP.NET 4.5 that makes it easy to combine or bundle multiple files into a single file. You can create CSS, JavaScript and other bundles. This means fewer HTTP requests and therefore helps pages load faster. When you set up bundling it also minifies the files which means the file size is smaller.

Another advantage of using bundling is that it removes duplicate references to files as it manages them for you. You just need to say which script or css bundles you require on the page and it sorts the rest out for you.

Before you get started

This is for MVC sites running ASP.NET 4.5 or higher.

You need to make sure you have the System.Web.Optimization package referenced in your project. If you don't have the package you can get it from NuGet:

PM> Install-Package Microsoft.AspNet.Web.Optimization

How to set it up for MVC

In the App_Start folder, you should have a file called BundleConfig.cs, if not then create it.

using System.Web.Optimization;

namespace CodeShare
{
    public class BundleConfig
    {
        // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
        public static void RegisterBundles(BundleCollection bundles)
        {
            //Scripts
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                "~/Scripts/jquery.validate*"));

            //CSS
            bundles.Add(new StyleBundle("~/bundles/style").Include(
                "~/css/style.css"));

        }
    }
}

Now in your views you can reference the bundles by using the following:

@Scripts.Render("~/bundles/jquery", "~/bundles/jqueryval")
@Styles.Render("~/bundles/style")

When you run the site in debug mode it doesn't bundle or minify. If you view source you will see:

<<span class="start-tag">script</span> <span class="attribute-name">src</span>="/Scripts/jquery-1.10.2.js"></<span class="end-tag">script</span>>

<<span class="start-tag">script</span> <span class="attribute-name">src</span>="/Scripts/jquery.validate.js"></<span class="end-tag">script</span>>
<span id="line152"></span><<span class="start-tag">script</span> <span class="attribute-name">src</span>="/Scripts/jquery.validate.unobtrusive.js"></<span class="end-tag">script</span>>

<<span class="start-tag">link</span> <span class="attribute-name">href</span>="/css/style.css" <span class="attribute-name">rel</span>="<a class="attribute-value">stylesheet</a>"/>

You can see that the jquery bundle pulled through the version number because of the use of {version}

You can also see that the jqueryval bundle referenced all files in the script directory that begin with jquery.validate because of the use of the * wildcard.

If you want to force it to bundle and minify the files in debug mode, you can add the following line after the last bundles.Add:

BundleTable.EnableOptimizations = true;

How to get it working in Umbraco

In order for this to work in Umbraco, you need to allow the bundles path to be used. You need to update this appSetting in the web.config file:

<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/bundles/" />

The next thing is to create a separate file in the App_Code folder called Bootstrapper.cs

The syntax is slightly different, the best way to show you is to do the same for what I did in the first example, but for Umbraco:

using System.Web.Optimization;
using Umbraco.Core;

public class Bootstrapper : IApplicationEventHandler
{
    public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication,
    ApplicationContext applicationContext)
    { }

    public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication,
       ApplicationContext applicationContext)
    {
       //Scripts
       BundleTable.Bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
          "~/Scripts/jquery-{version}.js"));

       BundleTable.Bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
          "~/Scripts/jquery.validate*"));

       //CSS
       BundleTable.Bundles.Add(new StyleBundle("~/bundles/style").Include(
          "~/css/style.css"));
    }

    public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    { }
}

Using bundling with Content Delivery Network (CDN) Files

The other thing you can do with bundles is to use the CDN file and fall back to the local version if it isn't available, like the below example:

using System.Web.Optimization;

namespace CodeShare
{
    public class BundleConfig
    {
        // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.UseCdn = true;

            //Script
            bundles.Add(new ScriptBundle("~/bundles/jqueryui-js", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js").Include(
                "~/Scripts/jquery-ui.min.js"));

            //CSS
            bundles.Add(new StyleBundle("~/bundles/jqueryui-css", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css").Include(
                "~/css/jquery-ui.css"));

        }
    }
}

I hope this has been useful for you, please let me know if you need any help with this.

If you'd like to know more about the fundamentals of MVC, why not use your 10 day free trial with pluralsight to go through ASP.NET MVC 5 Fundamentals