Inside ASP.NET 4.5 Bundling and Minification

Posted: November 27, 2011 in ASP.NET
Tags: ,

ASP.NET 4.5 has introduced built-in support for bundling and minification of javascript and css resources.Here minification refers to the mechanism of compressing the javascript & stylesheet files thus reducing the size of data to transferred over the wire. The process of bundling involves combining multiple javascript/css files into one, thus reducing the number of HTTP calls made from the browser. The following post by Abhijit Jana gives a nice illustration of the feature covering the basics and  the advanced areas as well.

http://abhijitjana.net/2011/10/06/bundling-and-minification-in-asp-net-4-5/

Having read this, I was just thinking about these elements/classes under the System.Web.Optimization namespace are all stitched together to implement the bundling and minification functionality.There were some design level questions as well like is the bundled content cached once created at server side or the bundling is done for every request?.

I went through the object model using the Visual Studio 11 Developer Preview and found the following key classes:

ASPNET_Minifier

  • BundleResponse – This class represents a resource bundle which contains the response after the resources are bundled and minified.
  • IBundleTransform – This is the interface, defining the contract for transformation i.e. Bundling + Minification
  • JSMinify – This is default implementation of IBundleTransform provided by the framework for javascript resources.
  • Bundle – This class represents a resource bundle with a list of files or directory from where resources needs to be read. This class accepts the type of transformer in the constructor as shown below:

public Bundle(string virtualPath, System.Type transformType)

NOTE:

  • Not quite sure why this signature accepts a System.Type rather than accepting an instance of IBundleTransform.
  • The IBundleTransform.Process method should accept a Bundle as input and return BundleResponse as output not a void return type with BundleResponse as input. This does not seem to be a good API design to me.

So I can understand logically that

  • A Bundle is defined by providing resource (js/css files & folders) locations
  • A class implementing IBundleTransform interface converts this to a minified and merged content and puts them in BundleResponse.

But how IBundleTranform.Process method is invoked? Is there any caching happening?

I implemented a small custom transform class which throws an Exception.

public class MyJSTransform:IBundleTransform
{
    public void Process(BundleResponse bundle)
    {
        throw new ApplicationException("...");

    }
}

The stacktrace captured is as shown below:

[ApplicationException: …]
BundingDemo.MyJSTransform.Process(BundleResponse bundle) in d:\Demos\BundingDemo\BundingDemo\MyJSTransform.cs:12
System.Web.Optimization.Bundle.GenerateBundleResponse(HttpContextBase context, String bundleVirtualPath) +99
System.Web.Optimization.Bundle.GetBundleResponse(HttpContextBase context, String bundleVirtualPath) +37
System.Web.Optimization.Bundle.ProcessRequest(HttpContextBase context) +25
System.Web.Optimization.BundleHandler.ProcessRequest(HttpContext context) +62
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +116
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

There are many methods which seems to be internal methods and classes, not visible through object browser. So a decompiler is the only resort. From the decompiled code we get some insight into the three critical method:

  • BundleHandler
    • This is an IHttpHandler implementation handling the JS & CSS resource requests
    • The ProcessRequestmethod
      • Get the Bundle from the Singleton class BundleTable.
      • Invokes Bundle.ProcessRequest  method
  • Bundle.ProcessRequest
    • This method retrieves the bundle url first
    • Invokes the GetBundleResponse method
  • Bundle.GetBundleResponse
    • Perform the cache lookup (normal ASP.NET cache with bundle url as key)
    • If there is a cache miss it calls GenerateBundleResponse
  • Bundle.GenerateBundleResponse
    • Create an instances of BundleResponse class
    • Set the files to be processed in correct order
    • Invokes IBundleTransform.Process

The storage of the JS content in Cache can be easily viewed using Quick Watch window as shown below:

image

The entire flow can be summarized as:

ASPNET_Minifier

About these ads
Comments
  1. Inside ASP.NET 4.5 Bundling and Minification « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. […] Inside ASP.NET 4.5 Bundling and Minification – Sankarsan discusses some of the details behind the Bundling and minification, looking at how the functionality is implemented in the framework, discussing how the functionality is called and the interactions between the parts. […]

  3. The various ability of asp.net 4.5 includes Improvements to HttpRequest handling, method for reading the request entity in a buffered way, support for performing flushes asynchronously using the BeginFlush and EndFlush methods of the HttpResponse class.

  4. Anyone else think this all looks very similar to https://github.com/jetheredge/SquishIt ?

  5. Ravi says:

    is there any support for embedded webresour/image in Bundling?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s