One out of all the WordPress APIs is often overlooked by developers – the Transients API. Sure, at the time you had started developing for WordPress, you first needed to get around in the system. But trust me, you definitely want to know how to use transients – because transients make your WordPress website faster. This is not only important to make sure that potential visitors don’t leave your site before it has even loaded, but also for SEO these days – Google & Co. put a lot of emphasis on your website’s page speed. The faster it loads, the better it possibly ranks. In any way, a faster page speed is better than a not-so-fast page speed. That’s why you need to use transients in your WordPress themes and plugins.
How do transients work?
It’s actually very easy to explain: A transient is a set of data that is (by default) stored in the WordPress database, exactly like all the options that come with themes and plugins. But there are two big differences:
- While options are stored permanently, transients can expire: Everytime you store a transient, you need to specify the number of seconds this transient will be saved (this is usually a very high number which corresponds to the number of seconds a whole week, month or even year has).
- There are some very handy caching plugins for WordPress which improve the results of using transients even more by implementing object cache. When you use such a plugin, transients are no longer saved in the database, but instead they will be stored persistently across page loads. The plugin I would recommend for this is the great W3 Total Cache plugin.
When should transients be used?
You could now think that transients should be used as much as possible. Generally, this is not the case. There are different opinions on this topic, but the what most of them have in common is the following:
It is recommended to use transients when…
- you’re using complex functions which create a good load of HTML code (store the HTML code in a transient instead of recreating it on every page load)
- you’re using complex database queries, for example to query recent posts, navigation menus or something similar (use a transient to store either the query results directly or the HTML code that is created using the query results; I recommend the latter)
- you’re connecting to another server to fetch information, for example when connecting to WordPress.org to retrieve plugin information or to the Twitter API to request your latest tweets (again, use a transient to store either the results directly or the whole HTML code that embeds the results)
How do I use WordPress transients?
There are three basic functions to know when using transients of which you will most certainly use the first two the most:
set_transient( $transient, $value, $expiration )
:
This function either creates a new transient with the name $transient
or, if the transient $transient
already exists, it updates the content of the transient. In both cases, the content that is stored in the transient is specified by the $value
parameter (it can be anything, a number, a string, an array… Finally, the $expiration
parameter defines how long this transient will be stored before it is regenerated (measured in seconds). You can either input an integer value directly or use one of the WordPress constants created especially for this case (they were introduced with WordPress 3.5):
MINUTE_IN_SECONDS
(60)HOUR_IN_SECONDS
(3600)DAY_IN_SECONDS
(86400)WEEK_IN_SECONDS
(604800)YEAR_IN_SECONDS
(31536000)
Of course, you can also combine a constant with another integer value, for example 3 * DAY_IN_SECONDS
would correspond to three days.
get_transient( $transient )
:
This function retrieves the content that is stored in the transient named $transient
. If this transient does not exist or has expired, the boolean value false will be returned instead.
delete_transient( $transient )
:
This function deletes the transient named $transient
manually. Deleting transients manually can be useful when you’re updating options that would change the output that is currently stored in the transient. For example, if you have stored the whole content of a widget in a transient and then you change a widget setting, you probably would like to have your transient regenerated immediately to apply the changes.
Note: Due to a limitation in the WordPress database, transient names must not be longer than 45 characters. Otherwise the full names cannot be saved which can lead to errors.
If you still have no idea how to use it, don’t worry, the examples are right below!
Hands-on Examples for using transients in your Theme or Plugin
How To Speed Up WordPress Navigation Menus
Whenever a WordPress nav menu is outputted (using the core function wp_nav_menu( $args )
), a complex function using multiple queries is executed. We can definitely speed that up a lot! Take a look at the following function that you can easily integrate into your own theme: Just replace the calls to wp_nav_menu
with a call to this function:
As you can see, at first the function tries to retrieve the transient with the name specified by the $theme_location
parameter (prefixed by ‘nav-‘, this is just for a better overview). Immediately after it, an if-clause follows that is only executed if the transient could not be retrieved (either because it doesn’t exist or has expired). So all that is done in that function in this case is outputting the transient’s content. If the transient could not be accessed, it will be (re-)generated by executing the if-clause. This clause simply contains the actions that are normally executed when printing a navigation menu in WordPress (just make sure that the ‘echo’ key in the array is set to 0 so that the nav menu is returned instead of echoed). After creating the navigation menu and saving it in the temporary variable $menu
, the new transient is set with the content of the $menu
variable and an expiration timeout of one week.
I hope you see how simple it is: After executing the above function for the first time, the transient exists for one week. So everytime the function is called again within this week, it works as fast as retrieving the transient and outputting its contents.
It is perfectly fine like this – there is just one thing you should take notice of: Since the expiration timeout is set to one week, the navigation menu is only “refreshed” once in a week. So if you make changes in this navigation menu, they won’t show up immediately, but only after the transient has expired. Some theme developers may be okay with it, and of course you could adjust the $expiration
parameter of the set_transient
call to make the period shorter, for example to refresh every day. The higher the expiration timeout, the less often the function’s more complex part is executed – but it also refreshes less often. You need to decide yourself how you’re gonna handle it.
There is, however, an alternative way: You could also set the transient’s expiration time to a whole year (or even longer) and delete the transient manually if something changes (I also like to call this ‘invalidating the cache’). In most cases, a navigation menu for a website does not change very often, so this might be the best solution. The only thing a little more complicated is figuring out all the places in the code that contain adjustments which would affect the content that is stored in the transient. For a navigation menu, this is not too hard – including the code below in your theme will do the trick.
The function above will only be called if the WordPress Core hook ‘wp_update_nav_menu’ is fired. This hook by default passes the ID of the menu that was changed to the function (the $id
parameter). The function now retrieves all the nav menu locations and checks which of them contain the menu that has been modified (a menu can possibly be found in multiple theme locations). If the modified nav menu is indeed tied to one or more of the locations, the transient(s) with the name of each location (again prefixed by ‘nav-‘, like in the other function before) is/are deleted. That means: if a nav menu without any defined location is changed, nothing happens (since we defined the transients according to the theme location and not according to the menu ID itself.
Note 1: The above code fully works, however there is one thing you should keep in mind: Unfortunately, the WordPress Core does not contain any hook that triggers when editing menu locations in the Manage Locations admin screen, so there is no way to delete the transient when modifications have been made in that screen. Please make sure to adjust all the changes in the Edit Menus screen (locations can be tweaked there too), and it will work fine. Just if you’re interested: A hook somewhere within lines 362-369 in wp-admin/nav-menus.php
passing the $_POST['menu-locations']
variable would fix this issue.
Note 2: Please be aware that you surely can only delete the transient manually if you have control over whether something changes. There are cases (for example when requesting information from another host, like your Twitter feed) where you’re not able to check if something has changed (and therefore cannot delete the transient accordingly). In these cases you simply have to adjust the $expiration
parameter to a period that suits you.
How To Cache A WordPress Widget
As a second example, you will see how to cache a WordPress widget using a transient. Since the code to do this has to be contained inside the widget class, it will only work for custom widgets. That’s not bad though as many of the WordPress Core plugins are cached by default. In this example we will create a simply Recent Posts widget (like the one that’s already bundled in the WordPress Core), but we will include featured images there. This example widget will not have any settings applied (except for the widget title), so we can fully concentrate on caching it perfectly. At first, see the widget code below.
Since it’s a whole widget, there’s still some code involved, but we’ll break it down into just a few parts which are important for us.
- First check out the
widget( $args, $instance )
function. Except for the$before_widget
and$after_widget
variables which are created automatically everything else that’s being printed is stored in a transient. When using transients with widgets, it is important to consider that a widget of the same type can be used multiple times on the site, so it would be not very clever to simply give it any name. When someone uses multiple instances of this widget, each instance would always look the same since all would share the same transient. That’s why we need to do it differently: the ID of the widget is perfect for this. It is created automatically by the parent classWP_Widget
and can be accessed anywhere within the class using$this->id
. So we simply use the widget ID (which is always unique) as the transient name. - In this widget, the code that creates the output goes from line 24 to line 100 (feel free to check out these lines, but they’re not what we will deal with here). Using the transient we not only “skip” these 76 lines, we also exclude some heavy database query (which is executed in line 35). As described earlier in this post, we could also be satisfied with only caching the
$results
of this query in a transient – but why doing that when we can also cache the whole widget content which is tied to the results anyway? The transient is (re-)created in line 99. - Now about deleting the widget transient: When you scroll down to the bottom of the class, you will find a simple function called
invalidate_widget_cache()
which consists of only one single line that deletes the transient. All we need to do now is hook this function to all the actions that could possibly change the content of this widget. There are four cases that this can happen – when we save a post, delete a post, change the WordPress theme or update the widget settings. The last thing is done internally in our widget (in theupdate( $new_instance, $old_instance )
function), so we directly call the function there that deletes the transient. The first three cases can be covered using WordPress hooks, so (in the constructor of this class) we use these three corresponding hooks and add ourinvalidate_widget_cache()
function to it.
Improve the Page Speed of your WordPress Theme (or Plugin!)
You’re ready to speed up your WordPress blog or website now – thanks to the easy-to-understand Transients API. Visitors and search engines will thank you.
I hope you found this tutorial helpful – let me know if there are any questions. Oh, and feel free to share your own ideas or concepts of using transients. There are probably lots of things in WordPress where speed could be improved using transients – just do not overuse it in places where it won’t help at all.
Leave a Reply