ASP.NET bundling and minifying open new opportunities for website optimization and help save traffic. Like other ways to improve performance bundling and minifying is not perfect and has its limitations. In this article we’ll show how it works in ASP.NET MVC.
What is batching and minification?
Bundling helps to download one type of file from site page with single request instead of downloading each file separately. Using fewer queries, pages download styles and script files. Minification makes files smaller by removing spaces, for example.
Together, both methods reduce the number of requests and bytes when the browser opens the page.
How do batching and minification work in ASP.NET MVC?
In ASP.NET MVC 4 applications, there is a file called BundleConfig.cs in the App_Start directory. This file contains a BundleConfig class that has only one method, RegisterBundles(). In this method, the downloaded files are bundled into packages.
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
"~/Content/themes/base/jquery.ui.core.css",
"~/Content/themes/base/jquery.ui.resizable.css",
"~/Content/themes/base/jquery.ui.selectable.css",
"~/Content/themes/base/jquery.ui.accordion.css",
"~/Content/themes/base/jquery.ui.autocomplete.css",
"~/Content/themes/base/jquery.ui.button.css",
"~/Content/themes/base/jquery.ui.dialog.css",
"~/Content/themes/base/jquery.ui.slider.css",
"~/Content/themes/base/jquery.ui.tabs.css",
"~/Content/themes/base/jquery.ui.datepicker.css",
"~/Content/themes/base/jquery.ui.progressbar.css",
"~/Content/themes/base/jquery.ui.theme.css"));
}
In the example, the files are divided into groups and combined into packages, each package is downloaded as a separate file. Consequently, the server will retrieve the following files.
~/bundles/jquery
~/bundles/jqueryui
~/bundles/jqueryval
~/bundles/modernizr
~/Content/css
~/Content/themes/base/css
If you look carefully at the file definitions, you’ll see that you can not only specify the file name, but also the path to it. A special {version} field in the file name means it can contain a version number. This template is especially useful for jQuery, since this library is updated frequently. When jQuery files are updated, the new files contain the new version numbers. And since the files differ only in version numbers, a package will be created for the updated files without any additional action on the part of the developer.
Remember that in debug mode batching is disabled by default. To enable it, you must add RegisterBundles() at the beginning of the method:
BundleTable.EnableOptimizations = true;
Let’s open the _Layout.cshtml view and see how the packages are connected:
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
ScriptBundle and StyleBundle classes
As you can see in the example above, script bundles and style bundles are created using different classes. The ScriptBundle class is designed for script files; files of other types don’t need to be added there. The same can be said about the StyleBundle class. Both of these classes inherit from the common Bundle class.
Minification works quite tricky. Bundle classes don’t do any file optimization themselves. All they do is add the desired minifactor to their transformation collections. There are two minify classes that are in the System.Web.Optimization:
- JsMinify
- CssMinify
These classes are the ones that do all the work of minifying files. Any developer can write their own implementation of minify. And if the same style is preserved as in the built-in classes, the bundling object can be given its own minifier.
Disabling the minification
It happens that CssMinify cannot handle some files. In case of such problems, bundling objects write comments in the processed files. These reports are created at the beginning of the files. So you need to be able to disable minification, but at the same time the bundling functions must work.
There are two ways to do this:
- Use the Bundle class. The Bundle class from which the other bundle classes are inherited is not abstract. You can create its object. And any files can be bundled in this way.
- Clear the transformation collection of the StyleBundle class. This is the same as using a Bundle class with an empty transformation collection.
Tips and Tricks
Here are a few hints on how bundling works.
- Bundles are cached. Unless otherwise specified, the first time a package is created, it is cached on the server. All subsequent requests are served and cached.
- Always test package creation. Packet creation may seem seamless. You just enable it when you deploy the site. But don’t forget about conversion classes. These classes may not handle some files. Make sure that the bundling and minification works correctly before you launch the site.
- Be careful with styles. When creating packages from style files, make sure that the package path has the same folder depth as the path to the original style files. If the style file uses relative links to images, those links will no longer work after the package is created.
So, bundling and minification are useful techniques for optimizing web page loading. Packages are easy to use and allow you to expand your capabilities. Almost all ASP.NET MVC templates use bundling. Thanks to a simple and flexible API, you can control all the nuances of package creation. It is possible to create your own package types and define file conversions with your own implementation.