We have years of experience developing and hosting WordPress applications. Over these years, through success and failure, we have gradually refined our development process into the well-oiled machine it is today. In this section we are going to share with you our best back-end optimization tools and techniques, and the best solutions we have found to address some limitations within WordPress.
The two biggest bottlenecks when it comes to WordPress application performance are almost always external requests and the database. Using object cache is the only way to get around querying the database or making external requests. Our goal is to cache everything that can be. The tools included here are the ones we consider to be essential for identifying the areas that need to be cached and building and tuning high performance WordPress applications. They are heavily used by our development team to ensure that we produce nothing but the fastest and most efficient applications.
An object cache plugin is the most important performance based plugin a WordPress site can have. Because core WordPress is built to take advantage of object cache, adding a caching plugin will provide the biggest boost to performance even if no other improvements are made to the theme or plugins. WordPress has a non-persistent object cache built-in. So, while data is cached during a single request to the server, all of that data is released after the request is complete. Subsequent requests to the site must query the database or hit external services again.
Our server setup already has Memcached running. To have WordPress take advantage of the object cache, there will need to be an
object-cache.php in the
/wp-content directory to override WordPress' cache interface. For this, we've always used Memcached Object Cache.
Adds a debug menu to the admin bar that shows query, cache, and other helpful debugging information.
The Debug Bar plugin is an essential tool when analyzing the performance of a WordPress install. Debug Bar is also extensible and has spawned a number of useful child plugins to increase it's functionality.
Debug Bar Extener adds additional tabs to the debug bar to help measure runtimes between checkpoints and lookup variable content.
This plugin provides very useful query debugging information. This plugin will tell you how many queries WordPress has made on a pageload, how long the combined queries took to load, and a reference to each query that has run. This is helpful for pinpointing the source of long load times. After page development is complete or after any major development, we use this plugin to identify any uncached queries that are running so we can add the proper caching around them.
Here is the result of loading the homepage on a rather large WordPress site.
Here is the same page loaded after memcached is running and many of the queries have been optimized to use object caching.
One thing that Memcached doesn't provide is a way to invalidate a group of data. To get around that, WP Cache Bucket allows cache items to be tied to a single validation key so they can all be expired at once without having to stick all of them into a single cache key.
Cache bucket uses the built-in WordPress wp_cache but contains methods to associate multiple items with a single cache group or 'bucket'. This is helpful when you have multiple items that need to be updated when one item is modified.
There are instances, such as nav menus, where if one item is updated, we need to invalidate all cached queries that reference that item. Because the key used to identify the cached menu is dependant on other variables when it's being accessed, there is no easy way to identify all of the keys that need to expire. WP Cache Bucket provides a wrapper around the cache that gives a "bucket" interface, allowing us to easily expire the entire set of cached menus when an object changes.
Adds ability to easily cache widget output for better performance.
Voce Widget Cache allows you to do output caching on widgets and define when you want the cache to be cleared and updated.
There are many instances where a client wants to use a 3rd party plugin to add additional widgets to their site. We've found, though, that many of the plugins in the WordPress community don't have caching built in. With Voce Widget Cache, we can easily add caching around another plugin's widgets without having to modify the plugin's source code.
WordPress' built in menu system is extremely query-heavy. Voce Cached Nav duplicates the functionality of
wp_nav_menu, adding caching at all possible levels. Replacing your template calls to
voce_cached_nav_menu will serve cached copies of WordPress navigation menus.
This plugin helps reduce queries that are run to get or render WordPress nav menus by caching them the first time it is queried. The nav menu stays cached until any nav menu is created, deleted, or updated or on the
save_post action for a nav menu.
For extremely slow tasks, just caching may not be enough. Requests that need the data from a slow process will have to wait on that process to complete whenever the cache expires. TLC Transients works around this by providing an interface with support for soft-expiration, background updating of the transients, and a chainable syntax that allows for one-liners.
TLC Transients uses the built-in functionality of WordPress transients but provides a very beefy wrapper to greatly improve the use of transients. This plugin allows for transients to be updated asynchronously in the background without waiting for cron or slowing page load. It will also serve old data until new data is available to prevent having to wait for a transient to update to serve content.
We frequently use TLC Transients when we are loading external data through a third-party api. The plugin provides a very useful interface for storing and updating data pulled in externally. Some external services can have slow response times and the soft-expiration of the plugin provides an excellent alternative to waiting for a response. This plugin, and the use of transients in general, is most effective when used with memcached.
No Stampede Actions provides an API to kick off globally singleton actions. It will lock the action to prevent other requests from kicking off the same action.
This plugin helps in cases of long running or resource intensive processes that need to run before a request can be handled. Ideally, avoiding these tasks altogether would be ideal, but there are times where there isn't a way around it. By using No Stampede Actions, we can prevent multiple requests from kicking off the same tasks and competing for resources. It allows the first request to create a lock on the task that makes the other requests sleep while the task runs. When the task is complete, the other requests can continue without having to run the task themselves.
Voce Performance Tools is a plugin we released that combines all of our favorite back-end optimization tools together in one plugin. Most of the plugins listed in this section are included in this plugin. This plugin also includes our Cached Queries plugin.