Minimizing page load time is incredibly important for both UX and SEO. We spend tons of time obsessing over getting our code and servers optimized to serve our sites as fast as possible, but once you incorporate data from external APIs, you may be putting your site’s load times at the mercy of an external server that you have no control over.
Even under the best circumstances, site performance will generally still be an issue when getting data from third-party APIs, due to the additional time required to make extra HTTP requests. For these reasons, it’s important to leverage a caching system when retrieving data from a remote site. While caching is important for any resource-demanding process, it makes even more sense when working with APIs because often times the data returned will not change between page loads.
The Better Transient Cache Option
While we could roll our own caching system based on the transients API, there are some important limitations to that system, which would restrict its usefulness. Fortunately, Mark Jaquith, a lead developer of WordPress has developed the WP-TLC-Transient, which provides an excellent tool for caching API calls.
The most important difference between the WP-TLC-Transients Library and the WordPress Transients API is that WP-TLC-Transients library is “soft-expiring.”
With the Transients API, on the other hand, you set a maximum length for the transient to be stored, once it expires, it’s gone — we call this system “hard-expiring.”At some point between when you set the transient and its expiration time, it will be cleared from your database, and any call to it will return false.
With the WP-TLC-Transient library, however, once information is cached, it stays in the cache, but is updated when called after its expiration.
Normally, when using the transient API, you set up a function that first checks if the transient is false. If get_transient() doesn’t return false, the transient is set and the cached value is returned. If it is false, the transient is re-built and only once that is done, the data is returned. This is the basic pattern for doing something like this:
function slug_get_from_remote( $id ) { $root_url = json_url(); $key = md5( __FUNCTION__ . $root_url . $id ); if ( false == ( $response = get_transient( $key ) ) { $url = trailingslashit( $root_url ) . 'posts/' . $id; $response = wp_remote_get( $url ); if ( ! is_wp_error( $response ) ) { $response = wp_remote_retrieve_body( $response ); $response = json_decode( $response ); set_transient( $key, $response ); } } return $response; }
This pattern is useful for more than just caching API calls. I often use it for caching computationally expensive, heavily-used functions, where the result doesn’t regularly change. With the WP-TLC-Transient — when you attempt to get an expired item from the cache — the old value is returned, and a new value is generated via a background, asynchronous process.
Adding the Library to Your Plugin or Site
WP-TLC-Transient library is not a WordPress plugin. It functions as a separate library that can be added to a site or a plugin, depending on your needs. While this is an uncommon practice in WordPress, it is very common in general PHP development, and is easily made, thanks to Composer.
Adding this library to your site or plugin requires adding: “markjaquith/wp-tlc-transients”: “dev-master” to your composer.json file. If you use composer, you can just include the autoload file it generates, and the library will be made available to you automatically.
Alternatively, if you choose to add the library using a Git Submodule or copypaste, you will need to make sure to include a file called “tlc-transients.php” in the library. This file begins by checking if the library’s main class already exists, and if so it aborts the loading process. It’s important to do it this way, opposed to loading the class file directly, as another plugin may be using the same library.
If you are using this library to improve a plugin for release, you will want it to be installed in a subdirectory of your plugin file. On the other hand, if you are doing development for a specific site and need to use it in multiple plugins, you might consider installing it in its own directory, such as Composer’s vendor directory, instead of each individual plugin. If need be you can include the tlc-transients.php file from a mu-plugin.
Using the Library
Once you have the library included in your site or plugin, using it is incredibly easy. The first thing you need is a function to make the request itself. For example, here’s a simplified version of the function I showed earlier, minus the caching:
function slug_get_from_remote( $param ) { $url = json_url( 'posts/' ) . $param ; $response = wp_remote_get( $url ); if ( ! is_wp_error( $response ) ) { $response = wp_remote_retrieve_body( $response ); $response = json_decode( $response ); return $response; } }
Now, instead of calling this function directly, we are going to wrap it up in a second function using the TLC Transient Caching library:
function slug_cache_from_remote( $id ) { return tlc_transient( __FUNCTION__ . $id ) ->updates_with( 'slug_get_from_remote', array( $id ) ) ->expires_in( 600 ) ->get(); } }
The new function slug_cache_from_remote gets the value of slug_get_from_remote() and then caches it. It uses slug_get_from_remote as its callback, since we specified it in the updates_with() method. In that method, we pass the ID of the post to get to the update with callback function as the second parameter. That second parameter is optional, but if it is used you must put the parameter in an array, which must only contain one index.
After that first time, it returns the cache value for the next 10 minutes, since I set 600 seconds in the expires_in() method. The least method in the chain is get(), which returns the cached value or the value of the callback function if it is called directly.
Technically, we do not even need the function, we could use its contents directly. Wrapping it in a function allows us to set the transient name programmatically, and to avoid redundant code.
That’s It
Using the WP-TLC Transient library is that easy. It’s a wonderful example of how open source allows you to easily solve problems, while taking advantages of the work of talented developers like Mark Jaquith. Don’t forget that while this article focused on caching responses from remote APIs, you can apply this design pattern to any computationally expensive function.
No Comments