WordPressish Beholding II

in code


Work and illness had the best of me last week. I was busy all the way through to the weekend, and at the weekend I crashed hard.

In the first part of WordPressish Beholding I used a waterfall analogy: I started at the top of the stream with servers. From there I descend into WordPress in this part. The final part will tackle the browser and frontend.

So in this article I look at ways for you to optimize your WordPress theme and site, from a developer viewpoint. There is less meat in this second part compared to the first or third (to come) parts, the third in particular. There’s lots for me to say about frontend optimization (I just wrote two thousand words on this for a client). I can talk about optimizations of of images, CSS, JavaScript and HTML to a stupid degree, but that has to wait for a week-ish.

Thing is, WordPress’ core does a great job of being a blogging CMS. The PHP framework is efficient and has a great depth of function. Stuff like the filesystem API abstract some messy crap. Sure, WordPress is a general garment. It doesn’t fit too well on some people, but it still fits.

As much as we love to piss on WordPress for shits and giggles, WordPress does its job well. The problem with WordPress is third-party code. I can say to you “use transients, cache stuff!” until I’m blue in the face, and you’ll listen, but then you’ll install a plugin that runs like a dog. Bad third-party developers and lay webmasters who want One More Plugin are the problem with WordPress. I’ll repeat last week’s extollation: think. Consider what you add and why you add it. Look at the plugin and ask whether you need it.

4. Transient API

The WordPress transient API allows you to cache database queries under a label. Transient data is temporary: it has a fixed expiry time in seconds, and when expires, it is gone forever.

So why use it? Transients are a waste if your blog is a stereotypical small WordPress site. The turnaround time to grab twenty posts for your blog, for tens to hundreds of visitors a day, is tiny. But if your site has thousands (or more) visitors per day, transients are a critical way to reduce page load. Here’s my use case:

The front page of the Kaitain theme (GitHub) queries up to 50 posts per load, while interior pages pull 25-30 each. That’s uncached, for each visitor. The overhead at peak hours can bog down the entire site.

I use transients to remedy this. This permits me to query featured posts only once every 20 minutes. I repeat this in all other widgets in the theme. Any custom query that I can put into a transient, I put into a transient.

I’ll talk through this with the function I linked:

/**
 * Get Featured Post
 * -----------------------------------------------------------------------------
 * @param   int     $count         Number of posts to retrieve.
 * @param   bool    $add_filler     Include filler post if query comes up short.
 */

function kaitain_get_featured($count = 8, $add_filler = false) {
    $featured = array();

    if ($count > 0) {
        $trans = 'kaitain_featured_posts';
        $timeout = get_option('kaitain_transient_timeout');

        $featured = array();
        $featured_list = kaitain_get_featured_list(false);
        $sticky_id = kaitain_get_sticky_id();

        if ($featured_list) { 
            if (!($featured = get_transient($trans))) {
                $featured = get_posts(array(
                    'numberposts' => $count,
                    'post_status' => 'publish',
                    'post__in' => $featured_list,
                    'orderby' => 'date',
                    'order' => 'DESC',
                    'exclude' => array($sticky_id)
                ));

                set_transient($trans, $featured, $timeout);
            }
        }

        $missing = $count - sizeof($featured);

        if ($add_filler && $missing > 0) {
            // Pad out query.
            $featured = kaitain_featured_filler($missing, $featured);
        }
    }

    return $featured;
}

There are three transient functions:

get_transient($name);
set_transient($name, $data, $expiry);
delete_transient($name);

Each is self-explanatory. The only thing I need to add is that get_transient($name) will return false if the transient was not found or has expired. In this way you use get_transient($name) to check if it exists. Simplified flow:

if (!($data = get_transient($name))) {
    $data = function_call($arg, $arg, $arg);
    set_transient($name, $data, $expiry);
}

If get_transient($name) returns false then perform function_call_whatever($arg, $arg, $arg), and save that as the transient. Important: never forget that a transient is temporary. It benefits a site under load by allowing you to cache heavy queries. You should never use it to save permanent data.

I’ll leave the expiry up to your own good judgement:

  • Is your site a personal blog with infrequent updates? Go longer. 12 or even 24 hours will be fine.
  • Is your site a busy news site? Go shorter. I picked 20 minutes for this project.

If you aren’t comfortable with time alone to control the transient, add a sentinel value. wp_count_posts is one great one, and another is a hook into publish_post:

function remove_stupid_transient($id, $post) {
    delete_transient('my_stupid_tranient_name');
}

add_action('publish_post', 'remove_stupid_transient', 10, 2);

I included the $id and $post arguments, to show that you can add further checks and actions. The two variables are the post ID and post object and there to use.

5. Cache

WP Super Cache settings

Chant ‘cache’ over and over and over like Matt Damon until it loses all sensible meaning, then chant some more. If you cache the ever-living fuck out of your website you can get away with shitty unoptimized code. There are a billion cache plugins for WordPress. Literally in no way hyperbolic; I found one thousand cache plugins on the WordPress plugin site, and ten people will give you ten different answers if you ask. I use WP Super Cache, authored by Donncha Ó Caoimh and Automattic, because:

  • Donncha is Irish. I’m Irish. Irish fistbump.
  • Automattic are the same handsome company who produce WordPress.
  • Its features aren’t first crippled and then married to a ridiculous upsell.
  • WP Super Cache applies sensible defaults. I can give this to a lay user to use: install, turn on, forget.

Yes, my criteria are petty and arbitrary. WordPress is a large set of PHP scripts whose execution generates a HTML page as a useful byproduct. WP Super Cache saves this HTML page and, based on Stuff, will serve this page instead of running scripts and queries.

The other side of WP Super Cache is that the popularity of the plugin Makes It A Target. I shit you not: there exists a website who warns that ISIS terrorists will take over your site if you use this plugin. But, for real, ware ye travellers.



Decompression

in me


Your email address will not be published. Required fields are marked *