Utilizing an fake CDN to boost Drupal’s page loading

Preamble

What are you talking about?

I want to address one of the most overlooked bottlenecks of modern web development here : the limitation from all modern browser to only process up to two HTTP-Requests parallel. Back in the day, that was a fine decision, because of unreliable and slow internet connections. But …

Nearly 20 years later the average internet connection is more than capable of handling multiple HTTP Requests at once. The problem is : All modern browser still want to be conform with the HTTP/1.1 spec, so we are still stuck with with a maximum of two parallel HTTP Requests.

This tutorial is about circumventing this restriction for the Drupal CMS and diminishing its impacts on the page load time for your Drupal website.

What is Drupal?

Drupal is an is a is a free and open source content management system (CMS) written in PHP and distributed under the GNU General Public License. It is used as a back-end system for at least 1% of all websites worldwide ranging from personal blogs to corporate, political, and government sites including whitehouse.gov and data.gov.uk – Wikipedia

What is an CDN?

A content delivery network or content distribution network (CDN) is a system of computers containing copies of data, placed at various points in a network so as to maximize bandwidth for access to the data from clients throughout the network. A client accesses a copy of the data near to the client, as opposed to all clients accessing the same central server, so as to avoid bottlenecks near that server. – Wikipedia

We are not exactly using a real CDN here, but using the mechanics of a CDN to reach our goal.

Introduction

The basic outline of this tutorial is it, to enable Drupal to handle more than two HTTP requests at a time. We want to do this, because DOM elements have a big, if not the biggest impact on end-user page load experience. A DOM element ( for example an image, each css file, each javascript file ) requires an extra HTTP request to be made. The main problem here is the HTTP/1.1 spec, allowing browsers only tp download two components in parallel per hostname.

Once loading your website for the first time, your visitors browser will first download the html source. Afterwards he will scan this html for all included components/DOM elements and then begin downloading the first two elements, then waits until they are fully loaded, selects the next two … waits again until they are fully loaded and so on.

That might not directly impact your load time if you are using a very lightweight site with very few media components, but it creates around 1 to 1,5 seconds of pure idling on every pageload for an average webpage with around 25 components.

We are now using the CDN concept to trick the browser into thinking that he is not downloading the components from one server thus allowing him circumvent the “two parallel downloads from one webserver only” rule and deliver our drupal webpage with max speed. We can do this, because subdomains of your main domain do not count as the same server. From a browsers point of view that are two different server.

Pageload – NormalPageload – With fake CDN

Setting up the fake CDN

 

Step 1 – Create the subdomains

You need to create 3 subdomains of your drupal main domain and point them all towards your drupal main install. I’m using css. img. and js. here, because they naturally fit into the patterns later on. You can name them as you wish, but make sure you insert the right domains in the third step!

For example

example.com points towards /home/www/drupal
css.example.com points towards /home/www/drupal
js.example.com points towards /home/www/drupal
img.example.com points towards /home/www/drupal

Back to top  

Step 2 – Install the CDN module

  • Download, install and enable the CDN module
  • You need at least version 6.x-2.0-rc5
  • You do not have to apply the Drupal core patch to make this working
Back to top  

Step 3 – Configure the CDN module

  • Go to the Details tab ( http://example.com/admin/settings/cdn/details )
  • Set the mode to “Origin Pull
  • Enter the following lines to the “Mode-specific settings

http://img.example.com|.jpg .jpeg .gif .png .ico

http://css.example.com|.css

http://js.example.com|.js

  • Save the configuration
  • Go to Other tab ( http://example.com/admin/settings/cdn/other )
  • Add the following lines to the whitelist

sites/default/files/js/*js
sites/all/files/js/*js

  • Optional : Remove *.js from the blacklist ( Only when you experience problems with your custom js files not getting rewritten. If that is the case, its still better to add the corresponding directory to the whitelist! )
  • Save the configuration
  • Go to the General tab ( http://example.com/admin/settings/cdn )
  • Set the “Integration method” to enabled
  • Save the configuration
  • Clear the Cache ( http://example.com/admin/settings/performance )
  • You’re done :)
Back to top  

Step 4 - Verify

Once you cleared the browsercache ( with CTRL + F5 on a tab where your homepage is open ) you should see in the websites sourcecode, that all your links to css, js or img files are now prefixed with either css.example.com, js.example.com or img.example.com.

If that is the case you have successfully set up your fake CDN and should notice an nice performance boost and overall faster loading speed on your website.

Back to top  

Step 5 – Possible problems

A direct quote from the CDN modules help page :

All JavaScript files are excluded by default. This is necessary to ensure a painless out-of-the-box experience. For maximum performance, you should only exclude problematic JavaScript files.

Full explanation: it’s necessary prevent any possible cross-domain AJAX requests, which would violate the same origin policy of browsers. Such violations potentially result in broken functionality. Note that even requests to subdomains such as cdn.yourdomain.com count as cross-domain requests!
You can opt-in to including JavaScript files by default and then exclude problematic ones, but then you should carefully note which JavaScript files perform AJAX requests. You can prevent all potential problems by using JSONP, which is a work-around to allow for cross-domain AJAX requests.

I did not ran into any problems on my heavy javascript websites, but in case your site is misbehaving :

  • Make sure you cleared Drupal’s as well as your browsers cache ( CTRL + F5 )
  • Remove the added *.js lines from the whitelist
  • Check the “Display statistics” box on the General Tab and see if your files are correctly mapped ( it will show a box on the page bottom on every non admin page )

Conclusion

A pretty easy way for such an massive performance boost. I managed to reduce the average load time of of my websites by around 2s each just by setting up fake CDNs.

Let me know in the comments if it helped you and feel free to ask questions. I’ll do my best to guide you through.

Back to top

About Mario Albrecht

Mario's first programming experience was a small calculation program written in BASIC on a Commodore Amiga in the early 90s. Since then, he as written code for dozens of companies and nonprofits such as Mednovo Medical Software Solutions, Telesense and ROOT Gaming. He creates modifications and tool for video games, like Diablo 2 and StarCraft 2, and helps out as technical administrator on various big internet communities and clans.

Mario uses Delphi as his language of choice for desktop development and PHP / Drupal for web applications. Mario loves challenging problems of any nature. If there is somebody saying "Thats technically not possible!" you'll most likely find Mario with his headphones on, working on a solution.

On weekend adventures, you'll find Mario playing a nice game of Magic: The Gathering or in a pub drinking beer.