Web Apps / Wordpress

WordPress Performance Checklist

by , , revisited on

We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.
Active subscription is required.

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 that 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 the 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 a 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 that can be used by a Linux expert

Sane updates approach

Updating to the latest version of WordPress and its plugins is good.
But the more plugins you have – the more frequent updates will be, and thus having to clear the cache.
Batch your updates instead and instead of relying on automatic updates provided by WordPress, use your own system.
For example, create a cron job that runs upgrades of WordPress and its plugins once a month only.
That means your cache is fully cleared only that often.

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 block 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 a shared hosting plan. There’s nearly zero chance you can earn from your website if you stay with a shared plan.

There’s a 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 a good experience with Hetzner servers.
Another alternative is OVH.

Async your scripts

Make sure to use async attribute for loading javascript:

<!-- Modern browsers will use 'async', older browsers will use 'defer' -->
<script src="//somehost.com/awesome-widget.js" async defer></script>

Set up Persistent Object Cache

WordPress performance for dynamic pages like WordPress admin can be greatly improved by setting up a general cache powered by Redis.

Use a full page cache plugin, or Varnish

A full-page cache plugin is a must, if you don’t make use of Varnish.
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).

Our FPC 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 invalidation support, so you can disable W3TC’s own page cache and only use the W3TC plugin for hole-punching Varnish cache automatically, after editing your website content.


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 frameworks are slow. WordPress is one of the frameworks with dozens of PHP files that 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 the 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 the 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

This means that the request is not returned by Varnish cache and our PHP backend (WordPress) properly handles the 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 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.

%d bloggers like this: