Speeding Up Default WordPress

This post is an experiment in getting a Vanilla WordPress installation as fast as possible. Why? – Speed is Good.

Update: You can read part two on images here.

A new WordPress install was set up on a test domain. The 2015 theme was activated, and all plugins were uninstalled. This is what we’re benchmarking:

defaultwordpress

You’ll note that there really isn’t anything to it at the moment. This is intentional – if we can get this as fast as possible, then we have a foundation to work from as the site grows.

Pingdom’s webpage speed test gave us the following benchmark from their six locations (Australia, Netherlands, Sweden, Texas, California, New York):

Pingdom SpeedtestOur absolute fastest benchmark (Amsterdam) loaded as follows –

amsterdam1That’s certainly fast. However, the large yellow block is the browser waiting for the server to start sending it the html for the homepage. Until the browser receives this, it doesn’t know which other assets (like CSS, Javascript or Fonts) to request.

Unlike static content, WordPress (the application) has to communicate with it’s database, which takes time, in order to assemble the html file it sends to the browser. Even for commonly requested resources like the homepage.

This is the first thing we tackle in the search for speed – if we can tackle the most significant delay for our fastest users, it should also have an impact on our slowest.

Server Side Caching

By default, W3 Total Cache will enable GZIP compression and browser-based caching. For the first test, this has been disabled.

At this point we install W3 Total Cache, which will allow us to make a number of performance changes. We first enable the ‘Page Cache’ feature:

pagecachePage Caching primes WordPress to prepare ‘here’s one I made earlier’ copies of more commonly requested resources – like the homepage and our ‘hello world’ post.

Once the cache has been created, and we wait a few minutes, we undergo another round of speed tests:

Speedtest2Our fastest page has dropped from 450ms to 257ms:

amsterdam2

Not bad. Our server wait time for the homepage has dropped substantially, from ~0.25 to ~0.025 seconds:

amsterdam2a

Can we break 200ms? In the search for speed we must explore some additional options.

Concatenation and Minification

Minification is a process of removing unnecessary characters (spaces, indentation, comments) from text files in order to reduce their size. They still (hopefully) function as intended. We use W3 Total Cache to perform minification for external JS & CSS files, and our HTML (including inline CSS and JS):

minification

minification2

Our homepage drops from 117 lines of html to 47. This knocks 22kb off the Page size. Concatenation means that 2 fewer requests are made:

requestcount

In terms of speed gains, we’ve shaved a few ms off, but nothing to get excited about.

Browser Caching

Using the Browser Cache settings we then encourage browsers to cache all static assets, and disable cookies setting for static files. Browser based caching shouldn’t make a difference to speed tests (as they typically represent a fresh user), but should make a massive difference to actual users viewing more than one page or returning to the site. This is also where we enable GZIP compression, which can have a substantial impact on filesize for text-based resources.

 

browsercache

After another round of tests we find GZIP compression has taken us from 452.9kB to 273.3kB:

fastestpageload4

Load in Amsterdam and Sweden drops below 0.25 seconds. For our Australian friends, this makes the biggest difference, dropping a second off the load time:

australia

Still – you can see a pattern with the connection and response (blue|yellow) being consistently the same speed:

2015-10-01 15_58_52-Website speed test

It’s the negotiation of each request here that’s costly. It has to come from Australia (where the internet isn’t great) and then go back to Australia, and then come from Australia and then go back to Australia.

Content Delivery Network (CDN)

A Content Delivery Network keeps copies of your assets on servers around the world. Requests for resources on your domain are directed to the most suitable (read: most local) cached copy. This can lead to faster delivery, among other benefits.

Cloudflare have a free CDN. We sign up for an account and enter our domain name, opting for the free plan. As part of the setup we update our nameservers at our registrar to those supplied by Cloudflare.

By default Cloudflare will serve your static assets (images, css, js), but will not be caching your html. This would keep our first Australian request slow. Luckily with the free account you get three rules, which is just enough to get the pages cached without breaking your wordpress access in the process:

  • yourdomain.com/wp-login.php* – bypass cache
  • yourdomain.com/wp-admin.php* – bypass cache
  • yourdomain.com/* – cache everything

It can take a little while for them to cache the static resources. You can check that Cloudflare is firing correctly by examining the headers either in browser, or with a utility like curl:

curl -svo /dev/null http://yourdomain.tld/resource

Once this is done, and to the best of our knowledge Cloudflare is up and running and caching the html, we retest.

Sorry Australia:

australia2
0.04ms of blazing gains.

I experienced similar performance gains across the board, the largest being in the US (which makes sense to me).

This is actually a bad test, Cloudflare needs enough requests from each location to make caching assets at each datacenter ‘worth it’. This wasn’t happening consistently, and this is a test domain with no traffic.

Browser Benchmark:

I also took internal benchmarks in Firefox using my own machine (in the UK, using UK hosting). These saw some substantial gains:

Initial Benchmark:

asdf
253.88KB, 2.19 seconds, 9 requests. No difference for repeat visit.

After Adjustments:

priming
232.22KB, 0.16 seconds, 7 requests. Repeat visit – 2.49KB, 0.03 seconds, 1 request.

We can load the optimised version 68 times in the time it would take to load the unoptimised version. While this is clearly not going to happen in the real world, it’s not a bad place to start a new domain.

Anomalous Results

One of the post-minification tests for Amsterdam saw the following:

anomalous

That’s a lot of waiting for the server, and an outlier in my tests. It does, however, illustrate the downside of shared hosting – at that moment the server was probably busy, which meant my performance suffered significantly.

In the next post I’ll discuss some of the experiments I’m running on this site for speed.

Leave a Reply

Your email address will not be published. Required fields are marked *