Hardening and speeding up a Wordpress blog

PHP is a fast scripted language, but when you build any reasonably sized website there are always optimizations and tricks you can do to make it go faster. Wordpress is no exception, and sometimes the extensibility, ease of customization and plugin framework it provides add overhead to the page loading time (and internal use of resources).

Also, Wordpress has a certain fame of not being too secure, having security bugs from time to time, so reinforcing the blog security is never a bad idea.

With this post I will provide a few points to improve both areas. Some like disabling login errors come from google searches and I can't remember the source (there are many results), others are my personal findings and Wordpress Codex readings.

All of this changes can be easily done either to the functions.php file of your theme. If the file doesn't exists feel free to create it, Wordpress will always check for it and parse it before rendering the page, or to the theme files in the case of literal substitutions and similar modifications.

On the security side:

  • Disable PHP error reporting & display

    ini_set('display_errors', 0);
    ini_set('error_reporting', 0);

  • Remove Wordpress version from <meta>. This way if a critical security bug appears (which is not uncommon with WP) you don't give clues to possible attackers of if your blog is vulnerable or not.
    remove_action('wp_head', 'wp_generator');
  • Disable login errors. Do not output if the username was correct but not the password. Just say "login failed".
    add_filter('login_errors', create_function('$a', "return null;"));
  • Want to filter user login to a specific IP? Add the following function with the desired address:
  • function CheckLoginIP($user, $username, $password) {
    return $_SERVER['REMOTE_ADDR'] == '192.168.1.1' ? get_userdatabylogin($username) : null;
    }
    add_filter('authenticate', 'CheckLoginIP', 10, 3);

On the performance side:

  • Remove the RSD <meta> if you don't need it or use the inline editor. Remember that this metas are sent on every request, so it's a few more bytes wasted.
    remove_action('wp_head', 'rsd_link');
  • Remove the Windows Live Writer <meta> if you don't use that tool.
    remove_action('wp_head', 'wlwmanifest_link');
  • Not using multilanguage and have a static design/theme that you don't plan to change more? Remove all _e() calls and place instead the literals.
    Change this: <div><?php _e( 'Archives', 'twentyeleven' ); ?></div>
    To this: <div>Archives</div>
  • Don't want all the admin dashboard widgets? Remove those you don't fancy.

    function remove_dashboard_widgets(){
    global $wp_meta_boxes;
    unset($wp_meta_boxes['dashboard']['normal']['core']['dashboard_incoming_links']);
    unset($wp_meta_boxes['dashboard']['side']['core']['dashboard_recent_drafts']);
    }
    add_action('wp_dashboard_setup', 'remove_dashboard_widgets');

  • If you don't have any strange hook for the header and footer rendering, using get_header(); get_footer(); and the like add some hook checks, file presence checks, backwards compatibility checks... and at the end by default they do a require_once (which by design and by logic shouldn't be ever created twice and thus is not needed).
    So, you can squeeze more CPU cycles by using this code for template loading instead:
    load_template(TEMPLATEPATH . '/header.php', false);
    load_template(TEMPLATEPATH . '/sidebar.php', false);
    load_template(TEMPLATEPATH . '/footer.php', false);

  • You can replace some calls that refer to your app path by their value if your domain is not going to change. For example:
    <link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>" />
    If the domain is going to be fixed (and the statics file path), why not placing the href directly?
  • Why not leverage some caching plugin? There are many, and if you want a custom made one, is also easy to develop

Comments?

Posted by Kartones on 2011-09-02