Introduction
When trying to optimize my old ASP.NET application, I found that many JavaScript files and CSS files are affecting the performance of my web applications. To optimize the performance of an application I found that bundling and minification can significantly improve the performance. It can be applied on MVC as well as in ASP.NET web forms. So I decided to get a hand on this. Before applying bundling and minification it is good to understand the basic logic behind this.
The following links were very helpful to me:
- http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
- http://msdn.microsoft.com/en-us/magazine/dn451436.aspx
Bundling
In ASP.NET bundling is a process of wrapping up all included files as a single downloadable resource so that the browser's call for resources is minimized. Instead of making a one-for-one call for each file, the browser gets all bundled files in a single call.
Minification
Minification is the process of the removal of all unnecessary characters, like extra spaces, comments, newlines, and so on, that have been added for readability, from files to reduce the size of files so that the data transfer can be minimized.
Let us understand it by an example. Suppose we have a function for sum:
- function sum(a,b)
- {
- return (a + b);
- }
Generally, when we write this function in a file, the entire JavaScript file is downloaded as it is. But with a minified JavaScript file the code above will look like:
- function sum(a,b){return (a+b);}
Clearly, it reduces the size of the file.
How Bundling works when a file is updated
Whenever an included file of the bundle is updated, a new token is created for the bundle query string parameter that forces a download full updated bundle the next time when a client request a page bundle has references.
When to apply bundling
- Having many common JavaScript/CSS files used throughout the application
- Too much JavaScript/CSS files in use in a page
Bundles should be created per usability in the pages where we actually need them. For example, an application common CSS file can be added to a single bundle, all common JavaScript files can be added to a single bundle. We even can create page-specific bundles.
Where we can Apply this: With ASP.NET we can apply it on MVC as well as ASP.NET forms or anywhere we are handling JavaScript/CSS.
Procedure to apply bundling: The following is the procedure to apply bundling.
Step 1
Add the Nuget package “Microsoft ASP.NET Web Optimization Framework”.
We can see that adding this Nuget package adds a few lines in our web.config files too as in the following:
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <dependentAssembly>
- <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
- </dependentAssembly>
- </assemblyBinding>
- </runtime>
Step 2
Add BundleConfig.cs to the App_Start folder. If the folder does not exist then please add it first.
Open BundleConfig.cs and add “System.Web.Optimization namespace” in the using section. The code of BundleConfig.cs will look as in the following:
- using System.Web.Optimization;
- namespace medAppz2.App_Start
- {
- public class BundleConfig
- {
- public static void RegisterBundle(BundleCollection bundle)
- {
-
- bundle.Add(new ScriptBundle("~/bundles/MyAppStartupJs")
- .Include("~/include/js/General.js",
- "~/include/js/Validation.js",
- "~/include/js/NormalAbnormalCheck.js"));
-
-
- bundle.Add(new StyleBundle("~/bundles/MyAppStartupCss")
- .Include("~/include/style/main.css",
- "~/include/Style/Container.css",
- "~/include/Style/BasicElement.css"));
-
- BundleTable.EnableOptimizations = true;
- }
- }
- }
See, there is a static method RegisterBundle that takes BundleCollection as a parameter. Then bundle.Add() methods have been used for creating ScriptBundle and StyleBundle. You can add n numbers of bundles depending on requirements. You can see, I have added four JavaScript files to a single bundle.
With the code above I have created two bundles: MyAppStartupJs and MyAppStartupCss. We will use these two in the next steps.
There is one more line to enabled bundling and minification of bundle references:
- BundleTable.EnableOptimizations = true;.
Step 3
Now to register the bundle in the Application_Start event of the Global.asax.cs file as in the following:
- protected void Application_Start(Object sender, EventArgs e)
- {
- BundleConfig.RegisterBundle(BundleTable.Bundles);
- }
Step 4
Now all the settings are done, we just need to add bundle references in aspx files.
Step 5
Add the following line to your page. It will allow the use of Styles.Render and Scripts.Render methods on the aspx page.
- <%@ Import Namespace= "System.Web.Optimization" %>
Note: With MVC we don't need to use the line above.
Step 6
To render these files you just need to write the following lines in your head tag. Of course, you can also add JavaScript bundles after the body tag and other places for better performance:
- <% Styles.Render("~/bundles//MyAppStartupCss")%>
- <% Scripts.Render("~/bundles//MyAppStartupJs")%>
We are done :). Now when calling a page request, if we look at the network exchanges in the browser, we can find that now there is only a single call per bundle for JavaScript and one single call per bundle of CSS.
If we check the page view source, in the head section, there will be a link for the bundles like:
- <link href="/BundlingAndminificationDemo/bundles/MyAppStartupCss" rel="stylesheet"/>
- <script src="/BundlingAndminificationDemo/bundles/MyAppStartupJs"></script>
In the same we can verify with the browser using the F12 -> Network section that shows the details of the bundle like size, type, download time and so on and confirms a reduced file size.
We can implement bundling in the same way with MVC too. Here we will need to render the bundles in the views (razor, aspx, and so on).
Point of consideration: Since bundling works on Application_Start, an application start will always be needed after modifying any included resource of bundles otherwise the new changes will not be reflected on the page since it will still be pointing to the older bundle.
Happy Coding.