Make WordPress AJAX Calls Cacheable and Improve WordPress Performance

WordPress Developers frequently make a very tiny but critical mistake when implementing wp_ajax calls that degrades WordPress performance and the scalability of  their website in cloud environments.

For instance, Daniel Pataki at WPMU offers a very clear and easy to follow tutorial on using the wp_ajax hook to make your web pages more dynamic. His example loads additional posts via an ajax-based pagination script. Very cool and very handy. Not only will it make you site more fun to use but also reduce overall server usage because the ajax call will be lighter weight than a full page view.

But once your site is on a modern cloud hosting infrastructure like WP Engine or Pantheon or Pagely, Daniel’s implementation will actually impede the performance benefits offered by these higher end hosts.

POST Requests Degrade WordPress Performance

Cloud hosts are usually running some sort of caching or “proxy”, usually Varnish, which dramatically speeds up your site load time. But POST requests are not going to get cached because it’s assumed that when POST’ing to a site your are performing a critical action like saving/submitting data.

But in the pagination example you’re just looking up what should be cacheable data. A GET request would allow the Varnish layer to serve that from cache much faster than would otherwise be possible. This also preserves your php resources for requests that actually need them and improves overall WordPress Performance.

Making this change is super simple (

 			url: ajaxpagination.ajaxurl,
-			type: 'post',
+			type: 'get',
 			data: {
 				action: 'ajax_pagination',
 				query_vars: ajaxpagination.query_vars,

WordPress Performance Tips

I’m becoming more and more obsessed with WordPress performance issues. Anyone running a site that is the slightest bit popular I amm sure has the same obsession. How do I get this site to load lightening quick! It is an uphill battle when using out-of-the box software and an especially steep hill using WordPress (why is an issue for another article).

So here are a few tips to help.

Don’t use a plugin unless you have to.

I’m not bashing plugins. Plugins are part of what makes WordPress such a great tool. There’s a plugin for just about everything and on low-traffic, low-usage sites you’ll be just fine loading up with 30 or 40 plugins. But as your site grows, you need to be aware that each plugin is performance drag … yes … even caching plugins at times.

The reason for this is obvious if you think about it. A plugin is designed for general usage … as it should be. A plugin developer has to anticipate multiple environments and prepare for as many of them as possible. They need to add user options. A stylesheet. A few javascript files maybe. And to make sure their functions are always available to end users, they load those functions as early as possible.

Contrast that with a custom approach. High performance PHP frameworks like CodeIgniter or Kohana make an artform out of limiting the resources used by a web application to exactly what is needed. If your website has a registration page, there’s no need to load any function or library that is not absolutely necessary for that process. But because every website is different, you have to make that discrimination on a case-by-case basis. Hence the word “custom”.

Budgets and resources will always limit how many plugins you can swap out with custom programming. And of course, if the custom programming sucks or the developer doesn’t understand how WordPress works, you’ll probably still be better off with a plugin. But if you can replace a plugin with a custom solution you’ll find it will help your performance.

Carpet Bombing Won’t Cut It

Most people take a carpet bombing approach to caching. Just install W3 Total Cache and you’re done. WTC is a great plugin and just having it installed is better than not having it installed. But if you have inefficient code, it won’t save you forever.

Let’s say you have a slow query that takes 3 seconds to run (hint: that’s waaaaay too long for a regular query). You turn on WTC page caching and no problem right? Except that page caching is turned off for logged in users, of which you have 30. And the page cache is dumped everytime something new is posted (including comments!!) and before long you’re still having crashes. The only difference is that now they are intermittent and seemingly unpredictable.

In the ideal world, you figure out where the slow query is and fix it. But at the very least you should know your site well enough to know where the bottlenecks are. And once you do you can target the trouble areas with a smart bomb instead of the usual napalm.

For instance, I have client using a Tabbed Widget plugin. It’s a good plugin but it just doesn’t scale. The client has ten tabs each with 10 to 15 sub-items. The way the tabbed widget code is written it takes some absurd number of queries to build it. Something on the order of 800!!! Seriously. So to smart bomb this widget you can actually use the WordPress Object Cache to cache the whole damn thing as an HTML object so that it is only rebuilt every so often.

Let’s say our troubled widget is in the primary widget area. We can do something like this in our sidebar.php:

$cached_widget = wp_cache_get('widget-primary-widget-area','custom-flag');
  ob_start(); ?>
The  stuff you want to cache

First we’re checking to see if $cached_widget exists by checking for it in the cache. If it isn’t there then you do what you would normally do in your sidebar, but precede it with ob_start(). Then take the buffered object and assign it to the $cached_widget variable and clean up with ob_end_clean(). Then set the object cache and give it an expires time of 60*60 which would mean it’ll refresh once an hour. Here’s what it would look like using a pretty standard sidebar.php.

$cached_widget = wp_cache_get('widget-primary-widget-area','custom-flag');
if(!$cached_widget) {

You can read more about Object caching here:

Lazy Loading

A concept used in the custom programming world that is often lost on WordPress developers is “lazy loading“. If you’re running a big site chances are your theme functions.php has gotten a bit crowded. I had one site whose functions.php got to 2000+ lines before we got around to reorganizing (not recommended).

As these files get bigger they become more burdensome to load. You should consider creating a directory called functions and storing “libraries” in that folder with a naming convention that makes sense to you. Then in your functions.php load those file using include_once($pathtofile);. You can then wrap these includes with standard WordPress conditionals to make sure they only load when you need them.

Lets say you have a special page template called page-directory.php. This page houses your super-awesome site directory that requires all sorts of special functions to make it work … i.e. custom javascript includes, a special stylesheet, and a few custom template tags. Doing something like this in your functions.php could help your performance by only loading that functionality when needed.

Wrap it up

There are a lot of advantages to WordPress and performance is NOT one of them. But a little planning and a little knowledge of how WordPress works you can get a long way toward a high performance site without giving up the many good things WordPress has to offer.