As I mentioned in WordPress caching part 1, WordPress has built-in caching that can be hooked into by plugins such as W3 Total Cache and Batcache (developed by Andy Skelton who is employed by Automattic).
In this article I am going to explain how I make use of WordPress internal caching – also know as the persistant cache – to speed up my site (and in turn Elemental).
What the persistant cache does is store the data you tell it to in a variable, so that the next time you use the data on that page you don’t have to touch the database. If you have software like Memcached and Batcache installed then the data will also be saved to memory – which means future page loads will skip the database entirely. There’s some documentation on the WordPress caching on the codex.
This might sound like a really obvious thing to do but surprisingly few developers make use of it.
As an example in Elemental I created a simple widget that grabbed a list of recent posts by a specific author. Before I learnt about the post caching I was doing 1 mysql query to grab a list of posts and then running the standard WordPress ‘loop’, which was then doing an extra query per post to get the relevant post information.
The problem was it didn’t matter what information I requested in my original database query, I would end up doing 6 queries (1 to get the list of posts, and then 1 for each of the 5 posts). Once I plugged in the caching the number of queries instantly dropped back to 1.
To use the caching you have to use the function wp_cache_add. Keep in mind that you should query all the post data in the table, even if you only need the title, this is because the cache may be used elsewhere on the page, and missing data will mean more data will need to be grabbed, which negates any savings you made.
So – what I started with was something like:
$sql = 'SELECT ID, post_title FROM ' . $wpdb->posts . '
WHERE post_author = ' . $primaryPostData['author'] . '
ORDER BY post_date DESC LIMIT 0, ' . $postAmount;
$posts = $wpdb->get_results($sql);
if ($posts) {
?>
<ul class="authorPosts">
<?php
foreach ($posts as $p) {
?>
<li><a href="<?php echo get_permalink($p->ID); ?>"><?php echo $p->post_title; ?></a></li>
<?php
}
wp_reset_query();
?>
</ul>
<?php
}
?>
… and after the caching I had the code:
$sql = 'SELECT * FROM ' . $wpdb->posts . '
WHERE post_author = ' . $primaryPostData['author'] . '
ORDER BY post_date DESC LIMIT 0, ' . $postAmount;
$posts = $wpdb->get_results($sql);
if ($posts) {
?>
<ul class="authorPosts">
<?php
foreach ($posts as $p) {
wp_cache_add($p->ID, $p, 'posts');
?>
<li><a href="<?php echo get_permalink($p->ID); ?>"><?php echo $p->post_title; ?></a></li>
<?php
}
wp_reset_query();
?>
</ul>
<?php
}
?>
Note: This example is hugely simplified and won’t work as a copy and paste job. It’s just outlined to show the differences between the 2 methods.
Traditionally the first example would be considered quicker. You are requesting just the data you need (only 2 fields) and then displaying it. However since the post data is not in the query cache the usage of the ‘get_permalink’ function means that additional database queries have to be made to get the permalink shortcode.
In addition, any time you use WordPress built in functions to get the data for this post again, they will already be in the query cache.
Usage
Using the function is simple. In my example above you have to pass an array of the post data, the post id, and the cache type – to be used as a key for retrieving the data later.
<strong>wp_cache_add($key, $data, $flag = '', $expire = 0);</strong>
param: int|string $key The cache ID to use for retrieval later
param: mixed $data The data to add to the cache store
param: string $flag The group to add the cache to
param: int $expire When the cache data should be expired
You can read up more on the wp_cache functions and their usage on the official codex page.
Note: if you are using the query_posts command, or pretty much any other built in WordPress function, then the caching will be taken care of for you. It will also, where possible, make use of any data you save to the cache as well
Was it good/ useful/ a load of old rubbish? Let me know on Mastodon, or BlueSky (or Twitter X if you must).
Link to this page
Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.