WordPress performance: 17 things to do right now

September 5, 2013 — 11 Comments

Wordpress PerformanceWordPress has a low barrier to entry and encourages experimentation, which are both good things for developers. But once a WordPress site is up and running, you need to get it running fast enough to keep Google happy. Luckily WordPress performance is easy to get started with: there are quite a few quick things you can do to improve the performance of vanilla WordPress installs.


  1. Check your loops first for expensive code. Optimization-wise, loops are low-hanging fruit. Use GLPTimer, cache grind, or similar to find bottlenecks. Focus on the WordPress loop and any other big loops. Minimise SQL calls inside loops: see #2. For other stuff commonly seen inside loops see #7 and #15.
  2. Start caching lookup data. Pre-fetch all the results you need in a single query, and store them in a single array. Optimize the query so it only selects the columns you actually need. For example: say for each post you also want to look up some taxonomy term names and slugs. If the loop is more than a few iterations, do this before your loop: run a custom query using $wpdb->get_results to select just those columns (and the ID!). Get them into an array keyed by the ID. Then, inside the loop, when you want to lookup the category data just use your array. This is a strategy that really pays off when your loop runs many times.
  3. Watch out for expensive dashboard code in functions.php. If you’ve added custom stuff for doing fancy things in the WordPress dashboard, surround them with is_admin() to make sure these bits of code are only executed when you’re actually in the dashboard.
  4. Remove plugins. Every active WordPress plugin will use resources, slowing down WordPress performance and potentially making it unstable. Anything the site is not using should be disabled. For example I often use the Regenerate Thumbnails plugin when I change the media sizes during development, then forget to disable it once the site is live.
  5. Disable unused apache mods. I don’t know of a good way to test which ones aren’t in use. There’s no rule of thumb here, you need to try switching off one at a time, then restarting Apache and testing. For what it’s worth, on my PHP hosting I often switch off Mod_Ruby, Mod_Dav, SVN features, Mod_Proxy, and setenvif.
  6. Enable some other Apache mods. yes, you read that correctly. Make sure you’re running mod_expires. Enable it if you have to, then read #12 to make the most of it.
  7. Hardcode for speed. Remove all those calls to get_template_directory_uri(), for example. Many people will disagree, but to me WordPRress themes are built this way because they have to be implemented on many sites. Once you have the site set up, go through and remove all the portable code. If you’re lazy and really just want to get the low-hanging fruit, you should do it to header.php, footer.php, sidebar.php and any other files that are included on many many pages. The loop and other template files that get included in many themes are also prime candidates for this. If files are called from a loop, consider getting rid of all the comments from them, and any other pieces of script inside loops.
  8. Remove whitespace from all your templates. Yikes, this might take a while if you’re doing it by hand. Luckily there are tools that can do this for you: try php -w original_source.php > cleaned_source.php from the command line / terminal. You’ll need to run it over all the PHP files in your theme, but the average theme is only 20-30 files. Think of the potential WordPress performance benefits!
  9. Get the best production-ready versions of js libraries. View the source your site is producing and examine the <head> line by line. Are you using minified versions of any jQuery plugins?
  10. View the contents of every css file you’re using. Minify. Remove comments, whitespace. Consider using a tool to identify unused declarations. See here for some pointers.
  11. If you’re feeling brave, try the Google pagespeed apache module. Some people have reported problems with it, but  I’m using it on 4 sites and I’m pleased with the speed improvement results so far. Also consider WP Super Cache.
  12. Timeline detective work. Use Safari’s Web Inspector Instrument > Network Requests / Chrome’s Network Tab to look at a timeline of the page load. Check the http response code of all the static files (ie javascript, css, and images). If they are getting served with a response of ’200′ consistently, try this simple set of .htaccess rules to force expires:
    FileETag MTime Size
    ExpiresActive on
    ExpiresByType image/gif "access plus 86400 seconds"
    ExpiresByType image/png "access plus 86400 seconds"
    ExpiresByType text/css "access plus 86400 seconds"
    ExpiresByType text/javascript "access plus 86400 seconds"
    ExpiresByType application/application/x-shockwave-flash "access plus 86400 seconds"

    …This sets all images, css, js, and SWFs to return ‘Not changed’ headers along with an Expires of now +24 hours if the browser’s request header has sent an ‘If-Modified-Since’ which is equal or newer to the file’s last modified time. English version: your site will encourage the browser to use a cached copy of static files where possible. You will need Mod_deflate enabled for this to work – see #6.

  13. Hosting under the microscope. Examine the Network Requests again. Check the very first item, which should be the html itself. There wlll be some initial latency, followed by a download. Examine this latency. If it is anything over 500ms after you’ve actioned all the changes above (particularly the changes to php/html) I would recommend looking further at server load, memory, and in general how suitable the web hosting is for WordPress. If you’re on cheap hosting, consider moving to good quality shared hosting at Bluehost or, if you have a few sites, look at getting a VPS, for example: MediaTemple DV (if you don’t want to manage it yourself, mt also offer a managed VPS: best of both worlds).
  14. Gzip. Also, again using Safari Network Requests tab, check the Size and Transferred columns for the base html document. If the two values are the same, then the html is not getting deflated, so you should look into using Mod_Deflate. There’s a good guide here.
  15. Get with the times. If you are using rand() or mt_rand(), replace it with openssl_random_pseudo_bytes(). See why here.
  16. Tuning Apache. If your hosting is on a VPS you might consider doing some performance tuning. If you have never done this before I would caution that it is easy to setup your Apache to fail during traffic spikes, maxing out the RAM on the server and requiring a reboot. You need to do some reading before attempting this. Here’s a quick primer.
  17. Optimising .htaccess. If you’ve never touched the default WordPress .htaccess you can probably skip this. But if you’ve added a bunch of rules you should consider doing what you can to minimise them. The classic example of this is the set of copy-and-paste anti-hotlinking rules that some web hosts recommend. I’d rather take the risk and not bog down my sites with a bunch of conditional rules that are going to get executed for every resource request.

Ok, that’s it for now. I hope you find something here to help with the performance of your WordPress site.

11 responses to WordPress performance: 17 things to do right now

  1. nice post, jay. I like to run my sites through gtmetrix to see if there are other performance enhancing tweaks to do. many of those are geared more for the intermediate developer.

  2. OR…. Just host it for free on WordPress.com, let the experts worry about this, so you can focus on content?

    • For blogging, sure. But lots of devs use WordPress as a cms framework for building big sites so they need to control the hosting. I’ve worked on complicated sites where the Web Designer has 15-20 plugins running (and that is not any kind of record, I bet some people run 50) and under those conditions speed becomes an issue! Cheers, J

      • True, I know what you are talking about, Designers love plugins since they need the functionality but they might not be able to write code.

  3. 18: Use opcode cache (eg APC)
    19: Replace Apache for Nginx
    20: Use page caching (cache plugin, Varnish, Nginx microcaching, etc)

    15 to 20 plugins (or more) is not the issue. It is just code, like the code in core. Having many badly coded plugins are an issue though. Make sure the plugins you use are well coded. Test each plugin for performance issues. Always test locally first and with debug=true to find obvious errors (you’ll be surprised how many plugins cause errors).

  4. Some really useful tips. I think going with the time is something WordPress itself also needs to do. But it always depends on availability.

    I do disagree on 7 and 8. Hardcoding things is a bad thing. And if get_template_directory_uri() can be faster then that should be fixed in core. Also I can see why removing whitespaces should speed up things. Specially when you only do it in the theme. Using an opcache what Daan suggested it the better solution.

    I do miss CDN in the list. It doesn’t speed up WordPress as in the PHP code but it does allow the server to handly more pageviews since most request will go to the CDN. This is even more important when dealing with Apache.

Trackbacks and Pingbacks:

  1. TWL #41 Wordpress Security and Performance Tips, Bot Filtering, and David Mamet - drunkonlife.net - September 6, 2013

    [...] WordPress performance: 17 things to do right now- Warning.  This is technical but in the scope of wordpress performance, doing these things can radically improve it for your website.  Too Technical? You can also check out Michael Gray’s recent post on performance as well. [...]

  2. Tweet Parade (no.36 Sep 2013) - Best Articles of Last Week | gonzoblog - September 7, 2013

    [...] WordPress performance: 17 things to do right now – Luckily WordPress performance is easy to get started with: there are quite a few quick things you can do to improve the performance of vanilla WordPress installs. [...]

  3. PHP $_SERVER - Some Things You Didn't Know - Go Learn PHP - September 17, 2013

    [...] HTTP_CONNECTION: another variable set from the client request. This one allows the browser to let the server know that it supports keep-alives. This sounds good, but http 1.1 (in widespread use) uses keep alives by default, so sending this in the request is pretty meaningless unless the request is http 1.0. Keep alives are used to enable persistent connections, which can save resources since the TCP connections are reused for multiple files instead of recreated for every request. In any case, it’s fairly common for server administrators to leave persistent conenctions enabled but set the timeout interval very low. This provides a good experience for well-beahiving, fast browsers, but tries to minimize the exposure to denials of service (where bad clients can open many connections without using or closing them, thus denying access to other clients). The increasing popularity of CDNs and other forms of distribution have again changed things, since they move resources away from the server that generates the html. And more recently, the massive increase in mobile traffic means that slower devices on slower (mobile) networks have forced some server admins to increase timeouts again. Upshot: performance is always an issue. For more on PHP performance, see this. [...]

Leave a Reply

*

Text formatting is available via select HTML.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>