WordPress 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.phpfrom 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!
- 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?
- 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.
- 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.
…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.
- 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).
- 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.
- Get with the times. If you are using rand() or mt_rand(), replace it with openssl_random_pseudo_bytes(). See why here.
- 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.
- 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.