Web Apps / Wordpress

WordPress Performance Checklist

by , , revisited on

We have by far the largest RPM repository with dynamic stable NGINX modules and VMODs for Varnish 4.1 and 6.0 LTS. If you want to install NGINX, Varnish, and lots of useful modules for them, this is your one-stop repository to get all performance-related software.
You have to maintain an active subscription in order to be able to use the repository!

Use proper testing tools!

First things first. Don’t rely on GtMetrix or PageSpeed Insights. If you absolutely must, test using GTMetrix with proper settings.

The best testing tool for performance would be anything that generates traffic to your website. SEO Spider tools which show request rates are good. One example is SEO Frog Spider. The free version will suffice for testing performance just fine.

We can also recommend the following online tests:

  • WebPageTest.org – it puts an accent onto Time to First Byte metric, which is great!
  • Test if your images are better with another format by using Cloudinary Website Speed Test
  • Pingdom has good test which is concentrated on total load time
  • Our own performance test does the job of checking your server via HTTP headers and give you configuration suggestions which can be used by a Linux expert

Use Cookieless domain for static files

For better cacheability, configure your nginx + WordPress installation with cookieless domain for images and other static files.

Use Sphinx

Sphinx provides significant performance improvement for delivery search results. Supporting plugin.

Don’t use Visual Composer

Visual composer ruins performance with its ajax-ed grids. Each grid bloc sends a slow POST request to admin-ajax.php which can’t be cached because it includes nonces (security tokens). Bad plugin design!

Choose proper hosting

Needless to say: if you are on shared hosting like GoDaddy, SiteGround or Dreamhost, etc. – forget about performance. There’s little chance that you can grow the number of website visitors if you stay with shared hosting plan. There’s nearly zero chance you can earn from your website if you stay with shared plan.

There’s 100% guarantee though, that your account may be suspended, in case your website does receive any decent traffic (many visitors).

Don’t worry, you can change hosting easily. Pay the same amount of money and get guaranteed RAM, CPU usage and bandwidth. All these are features of VPS or dedicated servers.

Budget hosting. VPS

At this time, our recommendation is Linode. Get a 2GB server for only $10 / month. It’s an offering from a very notorious VPS company which has been there for over a decade and known for its stability.

DigitalOcean and Vultr can be considered as well, but they can’t beat the latest Linode’s price offer yet.

Higher end. Dedicated server

We have had good experience with Hetzner servers.
Another alternative is OVH.

Async your scripts

Make sure to use async attribute for loading javascript:

Use a cache plugin

Our plugin of choice is W3 Total Cache. We did not select it by rolling the dice. The plugin supports a number of different backends for storing its cache easily. It also comes with Varnish support. For those, who don’t know what Varnish is – it’s a web accelerator and caching server which is the key component to excellent WordPress performance (read about it below).


AMP stands for Accelerated Mobile Pages.
Use AMP plugin for speeding up visitors who are landing up from Google search.

Use Varnish

Let’s admit it – PHP framework are slow. WordPress is one of the frameworks with dozens of PHP files which are parsed on every page request. Having W3TC cache pages to memory is one thing. Having Varnish cache pages to memory is another – it’s a more scalable approach since you can scale your server to many instances.

Setup WordPress cron properly

WordPress is usually run on a Linux powered web server. What’s the best way to run WordPress scheduled tasks on a Linux server? Of course the answer is – cron service of a Linux server 🙂 Provided you make use of the real Linux service for scheduled tasks and not some emulated PHP based WordPress calls – you will have increased performance and scheduled tasks will not be missed. We’ve covered this in WordPress cron optimization post.

Enable Conditional HTTP get

This is one feature of HTTP protocol that can help with both performance and even saving bandwidth to your users.
There is plugin for the purpose: If Modified Since.

The plugin doesn’t really support latest WordPress, but we have the fix for it. Edit the main plugin PHP file and replace:

if ( function_exists( 'http_response_code' ) ) {
    http_response_code( 304 );
} else {
    header( $this->get_http_protocol() . ' 304 Not Modified' ); 


status_header( 304 );

Let’s confirm things are working well.

Verify that conditional HTTP GET is working with your WordPress

We have example commands to test it with this page.

First, check that Last-Modified header is being returned by plugin:

curl -Is "https://www.getpagespeed.com/web-apps/wordpress/wordpress-performance-checklist" | grep Last-Modified

If there is “Last-Modified: Thu, 28 Jul 2016 10:09:35 GMT” returned (or similar), the plugin successfully sends the header in response. If the output is empty, something is wrong.

Next, confirm that conditional GET request will return empty response with 304 Not Modified status:

curl -Is "https://www.getpagespeed.com/web-apps/wordpress/wordpress-performance-checklist" -H 'If-Modified-Since: Thu, 28 Jul 2016 10:24:45 GMT' | head -n1

Will output “HTTP/1.1 304 Not Modified”

But wait, we have Varnish installed, and since the page is likely to be cached, it’s Varnish that handles conditional GET. We want to make sure that our uncached page still supports conditional requests. Let’s bypass Varnish by prepending a cookie:

curl -Is "https://www.getpagespeed.com/web-apps/wordpress/wordpress-performance-checklist" -H 'If-Modified-Since: Thu, 28 Jul 2016 10:24:45 GMT' -H 'Cookie: wordpress_test=1' | egrep 'HTTP|x-Cache'

Will give:

HTTP/1.1 304 Not Modified
x-Cache: uncached

Which means that request is not returned by Varnish cache and our PHP backend (WordPress) properly handles conditional request.

Note: if things don’t work for you using this page as a test, make sure to adjust the date you’re checking with, since this post will likely to be updated later on and thus change its modification time.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.