What is bundling and minification?
Bundling is the process of combining multiple CSS or JavaScript files into one single file, mainly to reduce the number of browser requests.
Minification is the process of sacrificing CSS and JavaScript readability for brevity by shortening variable names, removing spaces and line breaks, etc – all in the name of reducing file size.
Add the optimization package for ASP.NET MVC 4
Before we can use bundling and minification we need to add the ASP.NET Web Optimization Framework NuGet package to our project in Visual Studio:
- Right-click the web project and click Manage NuGet packages…
- …and search for Microsoft ASP.NET Web Optimization Framework and click Install:
Add CSS and JavaScript files to bundles
The first thing we want to do is define our bundles by specifying which CSS or JavaScript files should be bundled together. In standard ASP.NET MVC 4 projects the convention is to setup the bundles in a BundleConfig class inside an App_Start folder. However, for EPiServer sites you may want to use the EPiServer initialization engine instead.
Combine multiple JavaScript files into one
Since we want to setup our bundles when the website starts we’ll add an initializable module which will be invoked by EPiServer on startup:
[InitializableModule] public class BundlesInitializationModule : IInitializableModule { public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context) { // Setup bundles } public void Preload(string[] parameters) { } public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context) { } }
For this example I have two JavaScript files, one called video.js and one called main.js:
To define a bundle including these two files I add some code to the Initialize method of the BundlesInitializationModule class I created earlier:
BundleTable.Bundles.Add( new ScriptBundle("~/bundles/scripts") .Include("~/Static/js/video.js") .Include("~/Static/js/main.js"));
Note that I specify a virtual path for the bundle. This can be whatever you like, but the convention is to prefix the virtual path with “bundles”.
Next I include the files I want to bundle. Note the order of the JavaScript files as I want the contents of the video.js file to be included first in the concatenated JavaScript file.
Add a link to a JavaScript bundle in an ASP.NET MVC view
Now that we have defined our JavaScript bundle we can easily insert a link to it using the Render helper method and the virtual bundle path we specified earlier:
@Scripts.Render("~/bundles/scripts")
Note that you can link multiple bundles at once by comma-separating the aliases:
@Scripts.Render("~/bundles/jquery", "~/bundles/scripts")
The HTML output
The HTML output by the Render helper method depends on the debug setting of the web application. In other words, whether we have the debug attribute of the <compilation> element in web.config set to true or false:
<compilation debug="true">
When debug is enabled, the resulting HTML will link the original JavaScript files separately:
<script src="/Static/js/video.js"></script> <script src="/Static/js/main.js"></script>
However, if we disable debug…
<compilation debug="false">
…and reload the page we’ll see a link to the bundled and minified JavaScript file instead:
<script src="/bundles/scripts?v=A_gScVohD1KsFMa4Kp5Ku9rEJrzdJpYegYzDKQlaB4Y1"></script>
We’ll recognize the virtual path we specified for our bundle, but we can also see that a long hash has been added to the path. This is to ensure browsers can efficiently cache our bundled JavaScripts until the underlying JavaScript files are modified.
The JavaScript output
The original video.js file looked like this…
function playVideo() { // Just output an alert for now alert("I'll play a video!"); }
…and the original main.js file looked like this:
$(document).ready(function() { // Play a video playVideo(); });
If we browse to the bundled JavaScript (the path with the long hash) we can see that the two files have indeed been combined in the order I specified and then minified:
function playVideo(){alert("I'll play a video!")}$(document).ready(function(){playVideo()})
Combine multiple CSS files into one
Stylesheets are combined and minified in the same way as JavaScript files, we just need to use the StyleBundle class instead of the ScriptBundle class:
The bundled CSS file is also linked in the same way:
Include jQuery or other CDN-hosted JavaScript files
You can easily link a CDN-hosted JavaScript resource, including a local fallback if the CDN should become unavailable:
BundleTable.Bundles.Add( new ScriptBundle( "~/bundles/jquery", // Our alias "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.0.min.js") // CDN URL .Include("~/Static/js/jquery-1.9.0.js")); // Local fallback
Bundling and minifying LESS files
If you use a CSS framework such as LESS you need to add a bit of extra code to ensure the LESS code is parsed into CSS before bundling and minifying.
The following will create a bundle including two LESS files which will be parsed and minified:
BundleTable.Bundles.Add( new Bundle("~/bundles/styles", new LessTransform(), new CssMinify()) .Include("~/Static/css/foundation.less") .Include("~/Static/css/main.less"));
Note: the LESS transform above requires you to add BundleTransformer to your project (available on NuGet):