October 2017 : Online course in ASP.NET MVC / Core. Conducted by Bipin Joshi. Read more...
Registration for October 2017 batch of ASP.NET MVC / Core online course has already started. Conducted by Bipin Joshi. Book your seat today ! Click here for more details.

Optimize ASP.NET MVC Views with Bundling and Minification Features

ASP.NET MVC web applications often use client side scripting in one or the other way. Use of JavaScript libraries such as jQuery and frameworks such as AngularJS is quite common these days. Therefore it is important to pay attention to the rendering of the views. Especially, script load time is worth some consideration. Luckily, ASP.NET MVC offers help in the form of bundling and minification features. This article shows how these features can help you optimize the views.

Before we go into the details of bundling and minification features, let's try to understand the underlying problem these features intend to solve.

Web applications work on the basis of request-response model. While a page is being loaded in the browser, the browser also makes requests to load resources such as images and script files. That means if an ASP.NET MVC view is referencing four scripts using the <script> tag, the browser is going to send in all five requests - one for the main page and four for the script files. You can easily verify this using browser developer tools. The following figure shows how Chrome Developer tools show these requests:

Notice that there are four entries - one for /home/index (this returns the index view) and jquery-1.10.2.js, angular-1.2.js, angular-route.js and modernizr.js (Note: These libraries are used purely for testing purpose. Most of the JS frameworks or libraries have readymade minified versions). Also notice the size of each script file and the time taken for each to load. If you calculate the totals (script files only) they come to around 1093.2 KB bytes and 1665 milliseconds respectively. This default behavior causes performance penalty in two ways:

  • It is making five requests to the server. Every request is basically an "open-close" operation. More the requests poorer will be the performance.
  • The script files under consideration are downloaded "as is" - in their original (un-minified) form.

Bundling and minification features tackle exactly these two areas to improve the overall page loading time. They do so in two ways:

  • Instead of making independent requests to each script file, they make just one request and download all the necessary script or CSS files at once.
  • They minify the script and CSS files which results in a "compressed" form of the contents. The compressed content is then downloaded on the client side. This means fewer bytes travel over  the wire.

As you might have guessed by this time, bundling features take care of combining contents of multiple script or CSS files into one chunk whereas minification involves compressing this content. The resultant content is then download by the browser.

Now that you know what bundling and minification is, let's see how to enable it for your ASP.NET MVC application.

Open Visual Studio and create a new ASP.NET MVC application based on empty template. Then right click on the References folder and select Manage NuGet Packages menu option. In the Manage NuGet Packages dialog search for Microsoft ASP.NET Web Optimization Framework and then install that package. This package includes all the assemblies that are necessary to enable and use bundling and minification features. 

Next, add HomeController and Index view to the application as you normally do for any ASP.NET MVC application. Then add a bunch of script files to the Scripts folder. For this example I used jQuery, AngularJS and Modernizr libraries. Drag and drop these script files from the Scripts folder to the <head> section of the Index view so that <script> references for them will be added for you. The following markup shows how the <head> section looks like currently:

<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/angular-1.2.js"></script>
    <script src="~/Scripts/angular-route.js"></script>
    <script src="~/Scripts/modernizr.js"></script>

    <script type="text/javascript">
        $(document).ready(function () {
            $("div").html("<h2>Bundling and minification demo!</h2>");
        });
    </script>
</head>
<body>
    <div> 
    </div>
</body>

Notice that we have also added a small script block that simply sets the HTML content of a <div> to some message. This is done simply to test whether the libraries are downloaded correctly. If this message is displayed as expected we can rest assured that the libraries are successfully downloaded by the browser.

Now run the application and check (and note down) your results in Chrome Developer Tools. Based on the version of the script files and speed of your machine the results may vary from what is shown in the figure earlier. Also make sure that the <div> displays the message as expected. This is the normal execution of the application and doesn't use any bundling and minification features.

Now open Global.asax file and write the following code in the Application_Start event handler:

...
...
using System.Web.Optimization;

namespace BundlingMinificationDemo
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            ScriptBundle bundle = new ScriptBundle("~/scripts/myscriptbundle");
            bundle.Include("~/Scripts/angular-1.2.js",
                           "~/Scripts/angular-route.js",
                           "~/Scripts/jquery-1.10.2.js",
                           "~/Scripts/modernizr.js");
            BundleTable.Bundles.Add(bundle);
            BundleTable.EnableOptimizations = true;
        }
    }
}

Notice the code marked in bold letters. We import System.Web.Optimization namespaces because it contains classes necessary for availing bundling and minification services. Then we create an instance of ScriptBundle class. The ScriptBundle class represents a bundle of script files that can be accessed at a URL specified in the constructor (~/scripts/myscriptbundle). This URL is a virtual URL and doesn't point to any physical file. Just like ScriptBundle there is also a StyleBundle class that represents a bundle of CSS files.

Then the code adds all the necessary files to the ScriptBundle using Include() method. You can create one or more such bundles based on the pattern of usage of the script files. The newly created bundle is then added to the BundleTable object's Bundles collection. The EnableOptimizations property turns the bundling and minification on (true) or off (false). You may set it to false for testing and debugging purposes.

Finally, you need to replace all the <script> references from the Index view with a single @Scripts.Render() call that points to our script bundle:

@Scripts.Render("~/scripts/myscriptbundle")

The @Scripts.Render() method adds the required <script> references to the final HTML output. For rendering style sheets you can use @Styles.Render() method. If EnableOptimizations is set to false Render() will emit four <script> elements each pointing independently to a script file. On the other hand when EnableOptimizations is true you will get a single <script> reference like this:

<script src="/scripts/myscriptbundle?v=y4ZKq6H7v0q2Opkqq_qF3rJAbUUp9vwKJ5eJGz35Ktc1">
</script> 

That's it! If you run the application you should see some performance improvement. The following figure shows a sample run of the application after bundling and minifications enabled.

Notice that this time only one request (/Scripts/myscriptbundle) is issued to the server and it downloads 101 KB of data in 97 milliseconds.

That's it for now. Keep coding!


Bipin Joshi is a software consultant, an author and a yoga mentor having 22+ years of experience in software development. He also conducts online courses in ASP.NET MVC / Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Meditation and Mindfulness to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 22 September 2014


Tags : ASP.NET MVC jQuery JavaScript Performance