WordPress is estimated to power around 25% of the web. That statistic comes as a surprise to many people, considering the platform is not particularly modern or lightweight. At heart it’s a 15-year-old monolithic platform that’s jammed packed with features, and it’s those features that make it so appealing.

The achilles heel of WordPress is arguably its performance. With thousands of themes and plugins available to install in a couple clicks, performance can take a real hit. As the website grows, it’s starts to feel clunky and slow, and with your theme and plugins being so tightly coupled to the WordPress framework it becomes a game of Jenga trying to remove page weight.

Let’s take a look at a few ways that us as developers can speed up WordPress themes and plugins.

I have collated these performance tips from years of working on client websites using WordPress. Some methods in this blog post should not be followed if you are developing marketplace themes, as you are unlikely to know what the end user will do with your theme. 

Remove WordPress Emoji Scripts

The wp-emoji-release.min.js file was added to the WordPress core as of version 4.2. The file itself may only be a few kilobytes, but the WordPress emoji feature also adds an undesirable style block in the <head> of your site (with the dreaded !important rule).

If you don’t want or need Emojis it is super easy to remove them from your site. Add the following snippet of code to your theme’s functions.php;

// Remove WordPress default emoji scripts
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );

Asynchronously Load JavaScript in WordPress

I’ve found it uncommon to require render-blocking JavaScript in my WordPress themes. Nowadays I’m not really using frameworks like jQuery (which other scripts used to dependent on) and the JavaScript I write is loosely coupled. If that statement applies to your code, then your scripts are probably good candidates for async loading.

Let’s take an example of a JavaScript file called index.js being loaded;

function enqueue_scripts() {
  wp_enqueue_script( 'my-script', get_template_directory_uri() . '/index.js', array(), null, true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );

By viewing the source code you can see the script tag is correctly placed before the closing </body> tag.

<script type="text/javascript" src="{THEME_DIRECTORY_URI}/index.js"></script>

Now add the following snippet of code to your theme’s functions.php;

// Async load JavaScript files
function add_async_attribute($tag, $handle) {
  if ($handle === 'my-script') {
    return str_replace( ' src', ' async="async" src', $tag );
  }
  return $tag;
}
add_filter('script_loader_tag', 'add_async_attribute', 10, 2);

Take another look at the source code and you’ll see the script tag now has the async attribute.

<script type="text/javascript" async="async" src="{THEME_DIRECTORY_URI}/index.js"></script>

Loading Contact Form 7 JavaScript and Stylesheet

Almost every WordPress website I’ve built the client has wanted a contact form of some kind. It’s a pretty standard requirement for websites, and when it comes to WordPress, Contact Form 7 excels at it. Out of the box Contact Form 7 can build forms and send out confirmation emails, and with the help of the Flamingo plugin it can store the form submissions in the WordPress database and add a section in the wp-admin to show the data.

Stop loading the JavaScript and CSS Stylesheet

I frequently find myself in a specificity war with the Contact Form 7 stylesheet, as most of my forms have a different design to the default styling. What you can do however is prevent loading the CSS stylesheet and JavaScript file that ships with the plugin. You can do this one of two ways;

Add these define functions to your wp-config.php;

define('WPCF7_LOAD_JS', false);
define('WPCF7_LOAD_CSS', false);

Alternatively, add the following to your theme’s functions.php;

add_filter( 'wpcf7_load_js', '__return_false' );
add_filter( 'wpcf7_load_css', '__return_false' );

I usually just remove the stylesheet, as the JavaScript works well for most scenarios.

Load the Contact Form 7 JavaScript and CSS Stylesheet on certain pages

When a website has specific pages that contain contact forms, you can limit the loading of Contact Form 7 assets to these pages. It’s common to just have a “Contact” page that has a form. In that scenario I usually create a separate WordPress template for the contact page, and then add the following code snippet to the functions.php;

function cf7_scripts() {
  if ( is_page_template('template-contact.php') ) {
    if ( function_exists( 'wpcf7_enqueue_scripts' ) ) {
      wpcf7_enqueue_scripts();
    }
    if ( function_exists( 'wpcf7_enqueue_styles' ) ) {
      wpcf7_enqueue_styles();
    }
  }
}
add_action( 'wp_enqueue_scripts', 'cf7_scripts' );

The code above will enqueue the Contact Form 7 JavaScript and CSS stylesheet only if the page template is template-contact.php(change this to whatever you name your template).

Remove WordPress Embeds

WordPress 4.4 released Embeds. The code converts YouTube videos, Tweets, and URLs into fancy previews while you are editing. The JavaScript file wp-embed.min.js is loaded on every page of your WordPress site.

If you don’t want this feature (I rarely do), you can disable it across the site by adding the following snippet of code to your theme’s functions.php;

// Remove WP Embed in WP 4.4+ (video embedding)
add_action( 'wp_footer', function(){
  wp_deregister_script( 'wp-embed' );
});

Conclusion

We’ve looked at a few lesser known ways to speed up a WordPress site, but amends that can definitely help reduce page weight and speed up your website. During theme development I usually create a separate cleanup/optimise PHP file that I include in the functions.php. This separate file contains a whole bunch of these code snippets to optimise a WordPress site, which at some point I may convert into a WordPress plugin for easy reuse.