Super fast site architecture

Nov 06, 2012

The sexy web stack:

  1. Static pages with Jekyll (CMS)
  2. MaxCDN for the static asset server
  3. PJAX on the client side for faster content loading
  4. Apache for the server
  5. Hosting by MediaTemple (vs)

The results:

0.5 seconds time-to-paint in IE8 on cable network (measured with webpagetest.org):

Web page speed test

99% faster than all other sites tested on Pingdom tools:

Pingdom tools speed test

Super fast subsequent page loads. This you have to see for yourself. Click around this site (not the sidebar links) to see how fast subsequent page loads are.

Static pages with Jekyll (CMS)

To get my site blazing fast, I knew I had to go static. For this site, it's not practical from a cost perspective to put the HTML behind a CDN cache. If that were feasable, I could keep my site in WordPress and just throw a CDN in front of it. That would have produced very fast HTML transfer times. Instead, I ditched WordPress and switched to Jekyll. This turned out to be a very good decision for performance . Because my site doesn't need to have anything dynamic on it, there was no reason for it to be generated dynamically by a server from a database. Really, that just complicated everything. I fault myself for not using the right tool for the job.

Jekyll is a Ruby gem that you execute on template files and it spits out a completely static site (.html files only--YAY). It uses the Liquid template language which is wonderfully simple. Jekyll, however, does not offer anywhere near the features that WordPress does so you want to do some research if you're thinking about switching.

MaxCDN for the assets server

If you want to get serious about speed, you have to put your static assets on a CDN. All the big, serious web companies do this. We use Akamai on www.barackobama.com, but that is an enterprise level solution that is not cost effecient for a tiny little personal site like mine. I did some research and found a few CDNs that target customers like me. I chose MaxCDN because tt's very easy to configure and also very fast. My CSS and JavaScript files almost always transfer in less than 100ms. From what I can tell on the networks I use at home and work, transfer times range from 20ms to 100ms.

PJAX on the client side for faster content loading

PJAX is one my favorite things. I'm using it on this site to squeeze out even more load time. In the context of this site, when you're on the hompeage and you click on a blog entry, you're just asking to see the new content. Most of the code from page to page is the same so there is no reason for a completely new page load. When you do this, the browser has to parse the same stylesheets, JavaScript files and images as it did on the previous page. This is not the most effecient way. A different solution is to make the browser request only the content that is new and then inject the new content in to the document.

This idea in practice makes page loads very fast. It's difficult to measure because most web performance tools focus on full page loads. With this method you are essentially just removing all the time that it takes the browser to parse the stylesheets, JavaScript files and images that occur on both pages (minus the time it takes to parse the new HTML and inject it into the DOM). To see how fast this is, you really have to just see it with your own eyes. Click around on this site to different pages and see how they load in the blink of an eye.

This was a little challenging to do with Jekyll because you need to generate two different version of your pages/blog posts: the full HTML page and an HTML file with just the content. I was unable to find a Jekyll plugin to do this so right now my templates are just hacked together. It's a bit inefficient at the moment, but the time I saved in not having to worry about a database and PHP makes up for it. Hopefully soon I will have written a Jekyll plugin to do this.

In some cases this also has a latent affect of lowering the number of HTTP requests to your server. If you don't have client side cache headers on static assets then on the new page load, the browser will make a request for the same file it did on the previous page. With PJAX, the second request is not made.

Apache for the server

There's nothing really advanced about my Apache configuration. I'm using an edited version of the HTML5 Boilerplate Apache config. This is all in my httpd.conf instead of .htaccess because I hear it produces better performance this way. One thing about PJAX is that you need a way to pull both the full HTML of a page and just the content HTML. You don't want your users accidentally ending up on the content HTML URL. PJAX makes this relatively easy to solve by sending a custom PJAX header on all the requests that it executes. I added some Apache rewrites for PJAX that serve just the content HTML if this header is present.

In hindsight, I probably would have chosen Nginx instead of Apache. After talking with some friends and doing a little research, it looks like Nginx has better performance under high load levels and is also easier to configure. My site doesn't have high load levels, but I'll definitely take anything that is easier to configure.

Hosting by MediaTemple (vs)

I have come to really like (ve) hosting from MediaTemple. It's a simple solution, just a Linux (Ubuntu) box with root access and a dedicated IP address. Previously I was using MediaTemple's gridservice, but I found that to be slow with WordPress and my cluster seemed to go down too much.

Misc

In the sidebar of this site I have a little social network aggregator. This is the one piece of my site that is dynamic. To do this, I wrote a PHP script that hits the the Github, Twitter and Delicious APIs, and writes my activity to a static JSON file. I have a cron job that runs the PHP script every five minutes. On the frontend I make a JSONP request for the static file and use the data to inject the activity feed HTML into the sidebar.