Optimizing WordPress Themes for Speed

Return on Development

WordPress plugins and themes can speed up development. But unfortunately they can also include a lot of extra CSS and JavaScript that run on each page and can slow down your site. This article looks at a few different methods to improve your WordPress performance.

If you are concerned about site speed you will need to find a way to deal with this extra code — or choose a theme that has been minimized from the beginning.

Choosing a speed-optimized theme from the beginning seems like a great idea, but unfortunately speed can take a second seat to other considerations in this stage. Most clients are more concerned with the look and feel of a theme — and then the speed of a theme becomes a problem down the line, after a site has been published and is being advertised.

So what is a developer to do?

Cloudflare

You’ll want to make sure your site is on Cloudflare. Cloudflare can take care of a lot of issues for you:

  • Manage SSL certificates (free)
  • Offer CDN services (free)
  • Protect against bots (free)
  • Improve routing with Argo (paid)

The free version will almost always take care of your needs. I highly recommend it.

WordPress Cache Plugin – W3 Total Cache

I’ve tried a number of WordPress cache plugins. Some are more complicated than others. W3 Total Cache has been a steadfast option for me — it supports:

  • Page cache
  • Minify
  • Database cache
  • Object cache
  • Browser cache

I use this plugin to integrate with our ElasticCache server (Memcache) at AWS — but you can use a simple disk cache if you don’t have a Memcache setup or host support for it.

Server / Host Check

You’ll want to make sure your WordPress is hosted on a real server. My go to is WordPress hosted on AWS EC2 on Amazon Linux 2 — but you may find another host to be OK.

One way to measure how well your host is working is using the “ab” — the Apache HTTP server benchmarking tool.

ab -n 1000 -c 1000 https://www.example.com

This will perform 1000 requests, 1000 at a time.

Concurrency Level:      1000
Time taken for tests:   2.389 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      52763000 bytes
HTML transferred:       51961000 bytes
Requests per second:    418.65 [#/sec] (mean)
Time per request:       2388.617 [ms] (mean)
Time per request:       2.389 [ms] (mean, across all concurrent requests)
Transfer rate:          21571.63 [Kbytes/sec] received

Depending on your needs you may be OK with a lower performance server. But this is a good way to double check.

Another way to double check your server performance is to look at the PHP level. I’ve unfortunately had to do maintenance on a Managed GoDaddy server and they were still running PHP 7.2 in 2022 for new signups. If PHP is not up to date you can bet that other aspects of the server are not configured for your site speed. Save yourself the time and trouble and get on a better host.

WordPress Plugin Optimizer – “Plugin Organizer” by Jeff Sterup

The more plugins you utilize the slower your setup can become. Plugins can load additional CSS and JavaScript that can slow down your pages — even on pages that you don’t use the plugin shortcodes.

“Plugin Organizer” lets you prevent certain plugins from loading on certain pages. This can be an effective way to block poorly written plugins from loading massive JavaScript on each page.

WordPress Theme – Reducing Script and CSS Usage

Eventually, you’ll need to deal with the theme. That’s a bit of challenge.

First, make sure you’re using a child theme so the parent theme can receive updates. It may be simpler to remove script references in the header.php files or functions.php. But often you’ll need to use some scripts on some pages, so this approach is not sufficient.

This is an approach that I am working on that is showing promise:

/**
 * Reduce enqueued style/script handles
 * Based on:
 * https://lakewood.media/list-enqueued-scripts-handle/
 */
function rod_script_reducer() {  
  if( !is_admin() && is_user_logged_in() && current_user_can( 'manage_options' )) {

      global $wp_scripts;
      echo "<! --";
      echo "-- \n";
      echo " SCRIPTS \n";
      echo "-- \n";
      foreach( $wp_scripts->queue as $handle ) :
        echo $handle . "\n";
        echo "URL: " . $wp_scripts->registered[$handle]->src . "\n\n";
      endforeach;

      echo "-- \n";
      echo " STYLES \n";
      echo "-- \n";      
      global $wp_styles;
      foreach( $wp_styles->queue as $handle ) :
         echo "\"" . $handle . "\",\n";
         echo "URL: " . $wp_styles->registered[$handle]->src . "\n\n";
      endforeach;

      echo "-->";

  }

  global $wp;
  $current_url = home_url( add_query_arg( array(), $wp->request ) );      

  $blocked_scripts = array(

    // populate this array with the output from the page
    // add elements that you wish to block
    "contact-form-7",
    );

  if (strpos($current_url, 'page-to-optimize') !== false) {
    echo "<!-- rod-script-reducer enabled -->";

    foreach($blocked_scripts as $scripty) {
      wp_dequeue_script($scripty);   
    }

  } else {
    //echo "<!-- rod-script-reducer not enabled -->";

  }
  
}
add_action( 'wp_print_scripts', 'rod_script_reducer', 101 );

function rod_style_reducer() {  

  global $wp;
  $current_url = home_url( add_query_arg( array(), $wp->request ) );      

  $blocked_styles = array(
    // copy the CSS files that you wish to block here
    "simple-sitemap-css",
  );

  if (strpos($current_url, 'page-to-optimize') !== false) {
    echo "<!-- rod-script-reducer enabled -->";

    foreach($blocked_styles as $styley) {
      //echo "<!-- attempted remove: " . $styley . " -->\n";
      wp_dequeue_style( $styley );       
      wp_deregister_style( $styley );          
    } 

  } else {
    //echo "<!-- rod-script-reducer not enabled -->";

  }
  
}
add_action( 'wp_enqueue_scripts', 'rod_style_reducer', 101 );

This code removes JavaScript and CSS files on “page-to-optimize.”

I suggest taking a trial and error approach to see how many scripts and CSS files you can remove before you start to break that specific page.

This approach lets you remove specific theme integrations that you’re not using that the “Plugin Organizer” option may not let you handle.

© 2022 Return on Development, Seth Hayward