ASP.NET MVC 4 Highlights - Part 2: Bundling and Minification
In the first installment of this series, I explored a few of the new features in ASP.NET MVC 4, including the new default project templates, mobile templates, and display modes. Since that article, ASP.NET MVC 4 has been released to beta. For brevity’s sake, when I refer to MVC the design pattern, I’m referring to the ASP.NET implementation of the pattern. In this installment, I’m going to focus on one of MVC’s most useful features: integrated JavaScript and CSS bundling and minification. One of the most important considerations in any Web application is the size of the content rendered to the browser. Bundling and minification handle two important tasks. First, all of the disparate JavaScript and CSS files are combined into one or more files. Second, the JavaScript and CSS code is minified by means of removing all of the carriage returns and line feeds as well as verbose variable names in favor of shorter (less verbose) alternatives. With bundling, there are fewer resources that need to be rendered to the browser. With minification, the size of such resources is much smaller, often by as much as 70% or more! These are not new concepts. Tools like JSMin and YUI have been around for several years. You have always been able to incorporate these bundling and minification solutions. What’s new are the integrated features baked into the MVC framework that handle these bundling and minification tasks out of the box. Bundling and Minification “Out of the Box”
Figure 1 illustrates what you get out of the box for bundling and minification. Like all ASP.NET applications, everything starts in the Global.asax Application_Start() event handling code.  Figure 1: These code windows represent the out-of-the-box bundling and minification implementation in Global.asax and _Layout.cshtml. In that code, there’s a call to: BundleTable.Bundles.RegisterTemplateBundles();
The code for this method is burned into the System.Web.Optimization.dll. Figure 2 illustrates what that code looks like.  Figure 2: This code represents the out-of-the-box implementation code for RegisterTemplateBundles in System.Web.Optimization.The code is straightforward in that bundles are created and files are added to the bundles. There are two ways to add files. One way is to refer to the file specifically. The second way is to specify a directory along with a file pattern search string. In the second method, the code can selectively traverse subdirectories to add content. Each method has their respective pros and cons. When you specify the files, you know exactly what is getting into your bundled and minified files. This method requires more code. When you add directories, you don’t have to write as much code, but the possibility exists for unwanted code in the bundled and minified file. Choosing between adding files, directories or some combinatin thereof is a matter personal preference. To use this functionality, there are a few concepts you must be familiar with: - Bundle Class: Encapsulates one or more files to be bundled and minified
- AddFile() Method: Adds a specifically named file to the bundle
- AddDirectory() Method: Adds files that match a file search string within the specified directory
- Transform Property: An instance of IBundlerTransform, the object in this property performs the minification task
- Path Property: The string that identifies the bundle within the Bundles Member in BundleTables
As you will see in a moment, as is custom in MVC, if you don’t like the default out of the box functionality in MVC, you can substitute your own functionality. First, take a look at what the default functionality gives you. Figure 3 illustrates how the disparate javaScript (JS) and Cascading Style Sheet (CSS) files are rendered to the browser.  Figure 3: The network view lists the bundled and minified CSS and JS files (with a query string parameter that is explained in the next section).Note the file paths: /Content/css /Content/themes/base/css /Scripts/js
These are the paths specified when the bundles were created. Figure 4 illustrates how the minified JavaScript appears.  Figure 4: This is the minified and bundled JavaScript content as rendered to the browser.Why Is a Query String Parameter Added to the JavaScript and CSS Files? Every time the page is refreshed, the server-side code is executed, causing the _Layout.cshtml Razor Template to evaluate. You always want the client to recognize the latest JavaScript and CSS content. If the file were always named the same, the browser may reference its cache. This behavior can always be configured at the browser level. However, that is not usually a feasible solution because it requires each computer to be specifically configured. If you have the chance to control behaviors that are essential to your applications at the server level, take it! With the addition of the query string, the client will interpret this to be a new file and therefore, rely on its cache. You might be thinking that the call to ResolveBundleUrl is required for the bundling and minification to work. It’s not. To illustrate, I’ll replace the code for /Content/css with the following: <link href="~/Content/css" rel="stylesheet" type="text/css" />
Figure 5 illustrates that bundling and minification still takes place. The only difference is the file name. Without the call to ResolveBundleUrl, the query string parameter is not added.  Figure 5: If the ResolveBundleUrl call is omitted, a query string parameter will not be added.Essentially, that’s it! That’s what we get for free. But what about debugging? I don’t want my code minified in those cases. Am I stuck? Of course not! In MVC, with almost no exception, you can override the default out-of-the-box behavior for your own behavior. In the next section, you will see how to create your own custom bundler and minification class. | & | | 
By: John V. Petersen John Petersen has been developing software for over 20 years. It all started when, as a staff accountant, he was asked to get involved in a system upgrade to replace an old IBM Series 1 computer (about the size of a large refrigerator!). Those first programs were written in Clipper, Summer 87. Since that time, John’s tools included dBase, FoxBase, Visual FoxPro and Visual Basic. An early adopter of .NET, he then decided to go to law school. After practicing law for a few years, John realized that technology was a lot more interesting than the law. Today, John focuses on ASP.NET development and is having more fun than ever solving business problems for clients. John is a Practice Director for Custom Application Development at Neudesic, a Microsoft Gold Partner and the Trusted Technology Partner in Business Innovation. A 9-time recipient of Microsoft’s Most Valuable Professional Award, John is a current ASP.NET/IIS MVP. John is also an ASP Insider and is the INETA Mentor for PA and WV. John is the author of several books and is a frequent contributor to CODE Magazine and DevPro magazine. John holds a BS in Business Administration from Mansfield University, an MBA in Information Systems from St. Joseph’s University and a JD from the Rutgers School of Law – Camden.
email: johnvpetersen@gmail.com
blog: codebetter.com/johnvpetersen
twitter: @johnvpetersen
john.v.petersen@comcast.net ASP.NET MVC 4 at a Glance
The latest release of the ASP.NET MVC 4 framework has some new features including an enhanced default project template, templates for mobile applications, and recipes for code generation and enhanced support asynchronous methods. You’ll find additional announced features in the release notes: http://www.asp.net/whitepapers/mvc4-release-notes. Complete details on how to obtain and install the beta bits in Visual Studio 2010 or the Visual Studio 2011 Developer Preview can be found here: http://www.asp.net/mvc/mvc4. |