Bundling And Minification – Part-1

Bundling and minification are two techniques used in ASP.NET to improve request load time which in turn increases performance of a website. These techniques improves load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript.). So let’s see what Bundling and Minification means,

Bundling: It’s a simple logical group of files that could be referenced by unique name and being loaded with one HTTP requestor.

Minification: It’s a process of removing unnecessary whitespace, line break and comments from code to reduce its size thereby improving load times.

Let’s now see how these techniques can be implemented into a website supported by ASP.Net.

Install NuGet Packages

Firstly there are two NuGet packages that are required to be installed in your Visual Studio solution.

InstallNuget WebActivatorEx_Nuget

1) WebActivatorEx

Why do we need WebActivatorEx?

For bundling and minifying we need some code in Startup, even before global.asax’s Application_Start method is executed. WebActivator helps in doing so.

How it is done?
– Attribute the class with WebActivator
– Pass the type of the class
– Pass the name of the method to be executed

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(cssjsbundling.App_Start.BundleConfig), "BundleCSSJs")]

namespace cssjsbundling.App_Start
{
    public class BundleConfig
    {
        public static void BundleCSSJs()
        {

        }
    }
}

Dependency?

WebActivatorEx is dependent on Microsoft.Web.Infrastructure NuGet packages (libraries) so it will also get installed in your project along with WebActivatorEx.

2) Microsoft ASP.NET Web Optimization Framework

Why do we need Microsoft ASP.NET Web Optimization Framework?

It introduces a way to bundle and optimize CSS and JavaScripts files. This is what this post is all about so keep reading further.

How it is done?

Below code speaks it all,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(cssjsbundling.App_Start.BundleConfig), "BundleCSSJs")]
namespace cssjsbundling.App_Start
{
    public class BundleConfig
    {
        public static void BundleCSSJs()
        {
            var bundleTable = BundleTable.Bundles;

            bundleTable.Add(new StyleBundle("~/mysite/styles/css")
               .Include("~/content/styles/jquery.ui.accordion.css",

                "~/content/styles/jquery.ui.autocomplete.css",
                "~/content/styles/Site.css"
               ));

            bundleTable.Add(new ScriptBundle("~/mysite/javascripts")
               .Include("~/Content/scripts/jquery-1.8.2.intellisense.js",
               "~/Content/scripts/jquery-1.8.2.js",
               "~/Content/scripts/jquery-ui-1.8.24.js));
        }
    }
}

Dependency?

Microsoft ASP.NET Web Optimization Framework is dependent on few other NuGet packages (libraries) which in turn are dependent on few more packages, so they all gets installed in your project along with Microsoft ASP.NET Web Optimization Framework. Below is the hierarchy,

  • Microsoft ASP.NET Web Optimization Framework
    • Microsoft.Web.Infrastructure
    • WebGrease
      • Antlr
      • Newtonsoft.Json

Hence once your Nuget Packages are installed your project may look like,

NugetPackages

Note: If you run a project and encounter index out of range error you need to update WebGrease folder to latest version.

Dll that get referenced in a project are,

DLLReferences

Bundling

Before Bundling & Minification a project looks like,

Screen-1

Without Bundling & Minification, view source of a page looks like,

Screen-2

Once the NuGet packages are installed we now need to define a folder App_Start and introduce a class which will include all the definitions of css and js bundles.

Create a Bundle Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(cssjsbundling.App_Start.BundleConfig), "BundleCSSJs")]
namespace cssjsbundling.App_Start
{
    public class BundleConfig
    {
        public static void BundleCSSJs()
        {
            var bundleTable = BundleTable.Bundles;

            bundleTable.Add(new StyleBundle("~/mysite/styles/css")
               .Include("~/content/styles/jquery.ui.accordion.css",

                "~/content/styles/jquery.ui.autocomplete.css",
                "~/content/styles/Site.css"
               ));

            bundleTable.Add(new ScriptBundle("~/mysite/javascripts")               
               .Include("~/Content/scripts/jquery-1.8.2.js));
        }
    }
}

Changes to Web.Config file

Scripts and Styles tags will be enabled in .aspx file only if following setting in web.config file is made


  

      
        
      
    
  

Changes to .ASPX

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <%: Scripts.Render("~/mysite/javascripts") %>
    <%: Styles.Render("~/mysite/styles/css") %>
</head>
<body>

After successful Bundling & Minification view source of a page now look like,

BundlingDone

Tips

Minified JS

If you have minified versions of your JS files available do include them in the project with the same name as original JS file and add .min.js at the end of the file.

By default Minification will search for a matching file with .min.js and include that. If not, it creates a minified version by its own.

Bundle() Vs ScriptBundle()

There are two methods to add bundles, Bundle() and ScriptBundle() this might get a thinking what is the difference between them, the former will preserve the license headers (comments) whereas the later will strip out all the comments.

Also Bundle() will not minify .js files as compared to ScriptBundle(), thanks to Andy Cohen (my Development Manager) for updating me about this point.

Using Bundle()

bundleTable.Add(new Bundle("~/mysite/javascripts")              
               .Include("~/Content/scripts/jquery-1.8.2.js",
               "~/Content/scripts/jquery-ui-1.8.24.js));

Bundle-1

Using ScriptBundle()

bundleTable.Add(new ScriptBundle("~/mysite/javascripts")              
               .Include("~/Content/scripts/jquery-1.8.2.js",
               "~/Content/scripts/jquery-ui-1.8.24.js"));

ScriptBundle-1

Relative paths used in CSS

webfontscss

In case your css files contains a relative path which might be either referencing webfonts files or images in that case makes sure to use CssRewriteUrlTransform.

So your bundle code would look like

  bundleTable.Add(new StyleBundle("~/mysite/styles/css")
               .Include("~/content/styles/jquery.ui.accordion.css", new CssRewriteUrlTransform()));

Missing this out will give you 404 for the referenced resources in your css.

Debug Mode

Assume you are working on your dev environment and you want an option to debug your js files individually still take advantage of bundling and minification, interested to know how to do that?

It can be achieved in two ways,

1) In web.config file set debug value to true for compilation tag

debug-true

Debug value = false

debug-false

Alternatively set EnableOptimizations = false in your BundleConfig Class.

BundleTable.EnableOptimizations = false;

EnableOptimization-False

EnableOptimization-True

Nice Reads

WebActivator
Microsoft ASP.NET Web Optimization Framework
CodeProject – ASP.NET Web Optimization Framework
Programming CSS: Bundling and Minification
Bundling and Minification in ASP .NET MVC

That’s it this should get you started with Bundling & Minification.