Faster EPiServer sites – client side performance

First part of a new series where I’m going to focus on performance and scaling. I’m going to go through all the best practices we as EPiServer developers should know about, not only to create EPiServer sites that are fast, but ultra-fast.

You don’t actually need this section to enable gzip (IIS will just use it’s default settings), but it’s nice to know about it when you need to tweak your default gzip settings a bit. Basically urlCompression specifies what to compress and httpCompression specifies how. More information on httpCompression: HTTP Compression <httpCompression>.

If we check the applicationHost.config file for IIS 7 you can see the default settings (location: %windir%\system32\inetsrv\config\applicationHost.config):

Add Expires headers

Adding Expires headers to static and dynamic files like CSS, JavaScript and images tells the client to cache the files locally, lessening the burden on the server (less requests). Making your sites resources/components cache-able. More information: Add an Expires or a Cache-Control Header.

Back in our sites web.config file under the <system.webServer> section, we have the <staticContent> section:

You can only use one of these (if you’re not using the location element) at a time. I usually use MaxAge, it’s simpler and you don’t have to remember to update your settings when the date passes.

The important thing to remember is that if you make any changes to the static files you’ll need to use another name. You can add a querystring, change the name, or in some other way update the path to reflect that the file has changed.

Let’s update it to say that the client should cache the files for 1 year:

This helped bring the list of components down from 86 to 15. But we’re not quite finished yet.

EPiServer uses the location element to specify access rights and to use EPiServer’s StaticFileHandler for files located in Global Files, Page Files, Documents and other places that use Virtual Path Providers.

The caching setting is used to configure output caching for IIS. You have both output caching for IIS and for ASP.NET. More information: Caching <caching>. By default IIS output caching is turned on.

What EPiServer has done is told IIS to not cache static files like images, CSS and JavaScript and let ASP.NET handle it instead. You can read more about IIS output caching here: Configure IIS 7 Output Caching.

Let’s remove the whole <caching> section and use the default settings instead.

Now we have a score of 78 points in YSlow and 95 in Page Speed. Here you can see how much of the total size is now cached:

On the left we can see the total size and number of requests the first time, on the right is the size and number of requests after that. We’re now down to 3 requests and 16KB. Quite an improvement don’t you think?

Minify JavaScript and CSS

When we’re developing we usually work with multiple JavaScript and CSS files to make it easier to structure and maintain them. However in production we should take care to automatically compress and bundle the files.

It’s important to note the difference between the rule Gzip Components and Minify JavaScript and CSS, which will remove comments, unneeded whitespaces and replace variable/function names with shorter versions.

We’re going to use ASP.NET 4.5 Optimization preview. You can easily install it through NuGet.

Note: you’ll need to run .NET 4, so we’ll need to upgrade our solution to use .NET 4 instead of .NET 3.5. This is quite easy thanks to David Knipe. Change the projects target framework in Visual Studio and install the EPiServerCMS6ToNetFour package from nuget.episerver.com.

After that you’ll be able to install ASP.NET 4.5 Optimization successfully.

To enable it we just call the EnableDefaultBundles() method inside Application_Start in Global.asax:

Next step is updating the way external JavaScript and CSS files are included. By default, everything you refer to in a folder gets bundled together (only for the same type, so JavaScript and CSS files don’t get bundled together even if they’re in the same folder).

What I did was bundle the different JavaScript and CSS files into folders like components/modules and updated their references to use these folders instead.

There were a few inline scripts that I didn’t compress, but overall this helped a lot. I have now 97/100 points in Page Speed and 79/100 in YSlow.

Make fewer HTTP requests

Modern browsers can send up-to 6 requests at a time to the same domain. Older browsers up-to 2. Combining resource files like JavaScript, CSS and images into as few files as possible not only decreases the sites total size, but also make it load much faster for the client.

For JavaScript and CSS files we can use the technique we learned in the previous step (Minify JavaScript and CSS). For images we can use CSS sprites or embed the images.

Really great article! Have one problem though. I’m trying to set the ClientCache and staticFile expirationTime to something in the far future in our load balanced environment but nothing happens when looking in YSlow. Is it possible that there is something we have to do in the load balancer to get this to work completely?
/Martin

Leave a Comment

Currently you have JavaScript disabled. In order to post comments, please make sure JavaScript and Cookies are enabled, and reload the page.Click here for instructions on how to enable JavaScript in your browser.