Speeding up Kentico Websites with Rackspace CDN and Origin Pull

How to selectively apply a special type of "origin pull" CDN in order to get the performance benefits of a traditional CDN, while still retaining all the advantages of the highly dynamic and flexible Kentico platform

Andy Thompson By Andy Thompson. 14/09/2015. In Development, Kentico.

I recently published a post on Kentico Website Speed Optimisation Basics, which goes through a range of simple and effective ways to get your Kentico website purring.

This post focuses on one specific, more advanced performance optimisation technique: implementing a Content Delivery Network (CDN). I go into detail on how to selectively apply a special type of “origin pull” CDN in order to get the performance benefits of a traditional CDN, while still retaining all the advantages of the highly dynamic and flexible Kentico platform.

Some background on performance optimisation methods

PageSpeed/YSlow

Google (PageSpeed Insights) and Yahoo (YSlow) are two very popular resources that provide a range of recommendations for squeezing maximum performance out of your site. Kentico allows you to address many of them just by tweaking certain settings (and following best practices) within the CMS, however there are ways to go above and beyond just configuring out-of-the-box Kentico.

This post addresses three suggestions in particular from Yahoo’s YSlow:

  1. Use a Content Delivery Network
  2. Use Cookie-free Domains for Components
  3. Split Components Across Domains

These three all essentially point to smart use of a Content Delivery Network, or CDN. Sometimes that’s easier said than done though...

What is a CDN?

According to Wikipedia:

“A content delivery network or content distribution network (CDN) is a large distributed system of servers deployed in multiple data centers across the Internet. The goal of a CDN is to serve content to end-users with high availability and high performance.”

Challenges a CDN presents for Content Management

Static versus Dynamic

CDN usage is simple and easy for static assets, such as videos, or an archive of large file downloads. You simply load them into a CDN somewhere, and use that URL instead. For dynamic, or content-managed assets, it gets trickier.

Kentico likes to handle attachments (files such as images) differently

By default, Kentico stores images and other file attachments related to your pages in the database. Kentico then refers to them using a different URL, such as /getfile.aspx?guid=4aeb2ad7-317d-4457-aee7-845413a3346f. This enables us to do clever things like store multiple versions of a file, control access according to complex workflows, or dynamically resize an image to whatever dimensions we need on the fly, simply by adding a querystring such as ?width=200. This is what I’ll refer to simply as “content managed assets”.

There is of course an option to store files on the disk instead, however for the aforementioned features to work, we still need to allow Kentico to do clever things with where and how to store those files on disk.

This means simply storing your files on another server (or network of servers) distributed all over the world is not an option if you want to keep using these features.

Media libraries are stored in the Kentico file system

Media libraries work slightly differently to attachments in Kentico, in that you do get a predictable folder structure and can use direct file URLs to the files stored therein.

There are still database records containing metadata however, and Kentico does still like to manage the files directly. For example, the staging module tracks add/update/delete actions on media library files and can transfer the physical files between servers for you.

There is also the option to “use permanent URLs”, which in addition to giving us permalinks for our assets, allows for really cool stuff such as dynamic thumbnail creation and dynamic caching. We want to keep this!

Origin Pull CDN

Traditionally, a CDN provides us with a file store that we can access via a range of methods such as SFTP or a web interface. The files we load into that store are then distributed over time to various nodes in the network, and delivered intelligently to end users per request.

With an origin pull CDN, we don’t actually upload any files initially. We just configure it to point at a different location, in this case, our own website! When a user then requests an image via a CDN URL, for example http://assets.yourwebsite.com.au/images/logo.png, the CDN will either serve the file via the closest node if it already has it cached, but if it doesn’t, it will go and pull the file from the origin (your website) and then serve it.

Pros

  • Once set up, it needs zero maintenance! It is essentially a fully automatic service ongoing.
  • The CDN domains can be configured completely differently to your primary website domain.

Cons

  • Initial requests for new files (or files that haven’t been requested for a long time) will be slightly slower than before.

Rackspace CDN

The service we have chosen to use for our clients is Rackspace CDN. The Rackspace CDN offering utilises Akamai’s industry leading Content Delivery Network so with no lock-in contracts we have access to over 200 edge locations for just a couple of dollars per month.

The target audiences of our clients are mainly based in Australia and our testing here at Get Started has shown many major ISPs such as Telstra Bigpond host an Akamai CDN node, so being able to access the Akamai network nodes means that most requests for content don’t even leave the network of the Internet service provider/Mobile Carrier. This means less latency and faster download speeds when delivering your content.

Origin Pull CMS Issues

Many people will use an origin pull CDN to simply proxy their entire website. For example, they will have their actual site hosted at origin.mywebsite.com, and www.mywebsite.com actually points at the CDN (which then goes and fetches content from the origin site).

This is a very quick and efficient way to get more performance out of your website, if your issues are to do with static caching, high traffic bandwidth, or geographic location. This presents serious issues however for non-static websites, especially with an advanced platform such as Kentico EMS.

For example:

  • You’re losing some of the benefits of using a CDN however if you simply replace your domain with a single CDN domain, such as being able to “parallelise downloads across hostnames”.
  • Kentico will think every single visit to the site is coming from the same location - the CDN! This can wreak havoc with your Kentico analytics data, and make server-side personalisation practically impossible.
  • Kentico already provides very finely-grained control over HTML output caching, which you may lose if you add another layer of less intelligent caching over the top.

Ideally, we would like the best of both worlds: high performance, distributed hosting of our static assets, while the dynamic pages themselves are still served directly to our visitors by our Kentico site.

The Missing Link: URL Rewriting Output Filter

Our solution is to use our origin pull CDN selectively, retaining our primary domain (www.) for the dynamic website content, while serving file assets from different, optimised content delivery (e.g. images. or css.) domains. This will help us address the second and third points from the intro, relating to “cookieless domains” and “multiple domains”. And if we somehow get it all to happen automagically, then we have all the pros and none of the cons!

The way we do this is to tap into the power of Kentico’s output filters.

Kentico has a bunch of output filter options out of the box, from cleaning up your HTML, to improving HTML5 support, or even replacing table-based layout with divs.

By writing our own CMS.CMSOutputFilter.OutputFilter.CustomFilterHandler, we can tap into the OnAfterFiltering event, and run our own little piece of magic code to transform any references to images, CSS, JavaScript or other static files/assets, into references to our CDN. If you want help putting this code together, reach out to me and I’d be glad to help! If there’s enough interest, I might look at wrapping it up in a shareable module.

Here’s a heavily simplified snippet which should be more explanatory for the techies:

/// <summary>
/// Custom output filter event handler to rewrite local asset URLs to point to CDN
/// </summary>
private class OutputFilterEventsAttribute : CMSLoaderAttribute
{
    /// <summary>
    /// Called automatically when the application starts
    /// </summary>
    public override void Init()
    {
        // Assigns custom handlers to the appropriate events
        ResponseOutputFilter.OnFilterCreated += new ResponseOutputFilter.OutputFilterHandler(OutputFilter_OnFilterCreated);
    }
    void OutputFilter_OnFilterCreated(ResponseOutputFilter filter)
    {
        filter.OnAfterFiltering += new ResponseOutputFilter.CustomFilterHandler(filter_OnAfterFiltering);
    }
    void filter_OnAfterFiltering(ResponseOutputFilter filter, ref string finalHtml)
    {
        // Your magic code to do all the things goes here!
        // This is a very simple example to point /media/* references at a dummy CDN domain
        string cdnURL = "http://cdn.mywebsite.com";
        string pattern = String.Format("(['\"])(/media/.+)(['\"])", path);
        string replacement = String.Format("$1{0}$2$3", cdnURL);
        finalHtml = Regex.Replace(finalHtml, pattern, replacement);
    }
}

With this solution in place, our content editors can go about using the full power of Kentico CMS, blissfully unaware that their content is going to be drawn into a state-of-the-art CDN and served optimally to end users all over the globe.

Custom settings for control

The code sample above is very basic for the purposes of demonstration; as with any custom development within Kentico (or any platform/language for that matter) it’s a very bad idea to hard-code URLs or other settings into your code.

Kentico Custom Settings are beyond the scope of this article, but you should definitely read up on the documentation if you’re going to go down this path, especially if you’re going to reuse this method across a number of your sites.

See it in action!

Both of these sites use a hybrid approach where the primary HTML is served from our web server, but delivery of CSS, JS and images are served via Rackspace’s origin-pull CDN.

Get Started

Metricon

comments powered by Disqus

Andy Thompson

Andy is our CTO and Australia's only Kentico MVP.
Andy Thompson

Andy Thompson

Andy Thompson

Andy is our CTO and Australia's only Kentico MVP.