Make Your Plugin Faster With Conditional Tags

One of the reasons why WordPress can be slow is that it loads all active plugins on each and every page, even if some of those plugins aren’t actually used on that page. For example, an active anti-spam plugin will still be loaded even if the current page doesn’t contain a comment form (e.g. category pages and date archives). There’s not a lot we can do about that as users except complaining incessantly. However, if you’re a plugin author, there are a few tricks that you can and should use to make your plugin load only when required.

Divide And Conquer

The basic idea is to split the plugin into several .php files and load only the necessary components on each particular page. The main plugin file should contain only the code that decides which other files to load (e.g. by using conditional tags). For example, if your plugin only needs to run in the Dashboard, you could place all the important code in “admin.php” and put this in the main file :

/*
...the plugin header...
*/

//Are we running in the Dashboard?
if ( is_admin() ){
    //Load the actual plugin
    require 'admin.php';
}

This way all the complex functionality – the “meat” of your plugin – won’t be needlessly loaded when someone visits the blog’s homepage or browses the archives, and the site will be a little bit faster as a result.

The Tricky Part

The above example works fine if you use the is_admin() function, but it won’t work as expected with other conditional tags like is_single and is_category – they will always return false. This is because WordPress loads plugins very early, before it has parsed the current URL and figured out what it points to.

To get around this you can hook your loader script to the “wp” action. This action executes right after the query has been parsed and posts have been loaded, so the conditional tags will return correct values by then.

The new script might look like this :

//Are we in the Dashboard?
if ( is_admin() ){
    //Yep. Load the backend.
    require 'admin.php';
} else {
    //Nope. Set a hook to execute when other conditional tags are available.
    add_action('wp', 'load_test_plugin');
}

function load_test_plugin(){
    //You can use most conditional tags here.
    //For example, load the plugin only when viewing a single page or post : 
    if ( is_singular() ){
        //Load the actual plugin
        require 'core.php';
    }
}

And presto, optimization! :)

Caveats

  • You can’t use the above method if your plugin needs to interact with one of the actions/filters that run before the wp action.
  • Be aware of variable scope. When you include a file inside a function (like the hook above), any variables defined in the file will only be accessible from within that function. If you need a variable to be global, declare it explicitly with the “global” keyword.
  • Another thing to keep in mind is that in this scenario the __FILE__ constant won’t always point to the main plugin file.
  • It can be very hard to restructure an existing plugin to use the architecture suggested above, especially if it is very complex and needs to interact with many different hooks and filters.

Now I wish more of my 32 active plugins were optimized like this :) As far as I know, Ozh’s dropdown menu is the only one of them that uses this structure.

Related posts :

12 Responses to “Make Your Plugin Faster With Conditional Tags”

  1. Wesley says:

    I already try to do this as well. Best example for me would be my plugin “My comments elsewhere”.

    I also try to extract the admin options page and only include that when needed. Same with installation, uninstallation, widget control, etc.

    Good tip.

  2. Ozh says:

    Neat code snippets! The example & explanation about how early this loads and the ‘wp’ hook is a nice touch.

    Actually all my “recent” plugins (ie couple of years, probably not earlier) are structured like this. Similar advice goes with translation files (dont load them if they are not needed) which are more often than needed loaded.

  3. Sahar says:

    Thanks! this was a time & pain saver!

  4. [...] harus mengedit file plugin yang dipakai. Informasi lengkap bisa dibaca di blog Justin Tadlock, White Shadow, dan Coen [...]

  5. [...] harus mengedit file plugin yang dipakai. Informasi lengkap bisa dibaca di blog Justin Tadlock, White Shadow, dan Coen [...]

  6. [...] or if you are a plugin/theme author then please take a look at posts by Justin Tadlock, White Shadow and Coen Jacobs for more information on [...]

  7. Nicole says:

    Thanks! This is a great post. I would like to add about 30 conditional tags so that a difference sentence with 6 different links will appear on each different tag (i.e. tagged post will have a different sentence and set of links). Will this slow down my site?

  8. White Shadow says:

    I think that probably won’t affect performance much, though it may depend on how you implement it.

  9. Nicole says:

    Thanks very much for the reply. This is the code that I was going to use but I will be much longer. This is a sample with 2 conditions but I’ll have about 30.

    function add_tagtext() {
    if (is_single() && has_tag( ‘batman’ )) {
    ?>
    Batman disclaimer
    Hello
    Kitty Behavior Charts

    Hello Kitty Calendars
    Hello
    Kitty Reward Charts

    Hello
    Kitty Word Searches

    hello kitty disclaimer
    Hello
    Kitty Behavior Charts

    Hello Kitty Calendars
    Hello
    Kitty Reward Charts

    Hello
    Kitty Word Searches

    <?php }

    }
    add_action('thesis_hook_after_post','add_tagtext');

  10. White Shadow says:

    That should be fine, performance-wise. I believe both is_single() and has_tag() cache the relevant data, so calling them multiple times shouldn’t even result in additional DB queries.

Leave a Reply