Vulnerability in EPiServer.Forms

Try our conversational search powered by Generative AI!

Alexander Haneng
Jul 15, 2014
(3 votes)

EPiServer CMS Site Performance Part 2: Bundling and Minifying

Next we will look at reducing the number of requests, reduce bytes on the wire, and leveraging browser caching for our EPiServer CMS site to increase performance.

Bundling and minifying JavaScript and CSS files
A good place to start to reduce the number of requests and bytes is looking at the JavaScript and CSS files we have included on every page. On our site we have 3 CSS files and 4 JavaScript files, and Google PageSpeed complains about them not being minified and having too short browser cache expiration dates set (24 hours). We can combine the CSS files into one CSS file and the JS files into one JS file, minify the combined files and set the browser cache expiration date to at least 1 year into the future.

<!--CSS--> <link rel="stylesheet" href="/css/bootstrap.css" > <link rel="stylesheet" href="/css/style.css"> <link rel="stylesheet" href="/css/CloudClinic.css"> <!--JS--> <script src="/js/jquery.js"></script> <script src="/js/jquery.mobilemenu.js"></script> <script src="/js/jquery.ui.totop.js"></script> <script src="/js/jquery.equalheights.js"></script>

There are many ways to bundle and minify files using third party tools, but as of ASP.NET 4.5 it is included in the framework, so we might as well use that. Currently a default EPiServer CMS project is set to .NET version 4.0, so the first step is to set it to .NET 4.5. Right click the project in VS and select properties. Change “Target framework” to “.NET Framework 4.5” and build your project.


To get access to the System.Web.Optimization framework we need to install a package from nuget. Open the “Packet Manager Console” and run the following line:

Install-Package Microsoft.AspNet.Web.Optimization

Now we are all set to bundle our files.

Creating the bundles
If you don’t already have an “App_Start” folder in the root of your project, create it. Create a new class in this folder named “BundleConfig.cs”. In our case we have created one bundle for our JavaScript files and one bundle for our CSS files, but you can create multiple bundles.

using System.Web.Optimization; namespace CloudClinic { public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/Bundles/JS").Include( "~/js/jquery.js", "~/js/jquery.mobilemenu.js", "~/js/jquery.ui.totop.js", "~/js/jquery.equalheights.js") ); bundles.Add(new StyleBundle("~/Bundles/CSS").Include( "~/css/bootstrap.css", "~/css/style.css", "~/css/CloudClinic.css") ); } } }

Registering our bundles
We need to register our bundles in the Global.asax.js file like this:

using System.Web.Mvc; using System.Web.Optimization; namespace CloudClinic { public class Global : EPiServer.Global { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); //Register JS and CSS bundles BundleConfig.RegisterBundles(BundleTable.Bundles); } } }

Using our bundles
Now we can swap our old CSS and JS files with the new bundles in our .cshtml file.

<!--CSS--> @Styles.Render("~/Bundles/CSS") <!--JS--> @Scripts.Render("~/Bundles/JS")

The end result
By loading the page again and viewing the source we can see the end result. (Note: If you have debug=”true” in your web.config the files won’t be bundled, so make sure to set it to false first.) The files have been bundled into just two files, they have been minified, the browser cache expiration has automatically been set to 1 year into the future and by adding a version hash query string we ensure that if we make any changes to the files the browser gets the latest version.

<!--CSS--> <link href="/Bundles/CSS?v=GSQWO59HgwIEQn34xDiBFOx9GFxcmzxP29G-QcjFvn41" rel="stylesheet"/> <!--JS--> <script src="/Bundles/JS?v=pUrWyl423vnnVLCmPyX5AF4ZNMCq1q65jNhtv0FcBL41"></script>


Bytes transferred: 326.5KB (was 333.3KB)
Requests: 30 (was 35)
Time: 1.16 seconds (was 1.27 seconds)


Go to Part 3: Optimizing images and using sprites

Jul 15, 2014


Petter Klang
Petter Klang Jul 15, 2014 12:43 PM

What happened to the minifying part? =)

Jul 15, 2014 12:53 PM

Bundling, minifying and far future cache expiration is all done in one operation. :-)

Petter Klang
Petter Klang Jul 15, 2014 01:47 PM

So minfiying only gave you 0.6k on your js?

You only writing a and b as variable names from the start then? =)

Petter Klang
Petter Klang Jul 15, 2014 02:08 PM

Don't you need the BundleTable.EnableOptimizations = true;?

Jul 15, 2014 02:15 PM

Of course I only user a and b as variable names. Descriptive variable names are for wusses. :-)

The reason is that jquery.js already was minified and the other 3 JS files are pretty small (5KB in total).

The minification of the CSS files however saved me 6KB.

Jul 15, 2014 02:17 PM

You only need to set BundleTable.EnableOptimizations = true if you want to run the site with files bundled and debug = true.

Petter Klang
Petter Klang Jul 15, 2014 02:28 PM

I see, thanks for the clarification.

valdis Sep 12, 2014 10:58 AM

What about bundling conditionally? :) I cases when you need to reproduce client-side issue directly in production env..

valdis Sep 12, 2014 10:58 AM

What about bundling conditionally? :) I cases when you need to reproduce client-side issue directly in production env..

Sep 12, 2014 02:46 PM

Valdis: If you need to debug javascript in production you can:
a) Set debug = true in web.config
b) Set BundleTable.EnableOptimizations = false in code.

Please login to comment.
Latest blogs
Join the Work Smarter Webinar: Working with the Power of Configured Commerce (B2B) Customer Segmentation December 7th

Join this webinar and learn about customer segmentation – how to best utilize it, how to use personalization to differentiate segmentation and how...

Karen McDougall | Dec 1, 2023

Getting Started with Optimizely SaaS Core and Next.js Integration: Creating Content Pages

The blog post discusses the creation of additional page types with Next.js and Optimizely SaaS Core. It provides a step-by-step guide on how to...

Francisco Quintanilla | Dec 1, 2023 | Syndicated blog

Stop Managing Humans in Your CMS

Too many times, a content management system becomes a people management system. Meaning, an organization uses the CMS to manage all the information...

Deane Barker | Nov 30, 2023

A day in the life of an Optimizely Developer - Optimizely CMS 12: The advantages and considerations when exploring an upgrade

GRAHAM CARR - LEAD .NET DEVELOPER, 28 Nov 2023 In 2022, Optimizely released CMS 12 as part of its ongoing evolution of the platform to help provide...

Graham Carr | Nov 28, 2023