WordPress and Google Pagespeed optimisation of blocking javascript

When you include scripts in your WordPress theme using the prescribed functions wp_register_script and wp_enqueue_script you can use the fifth parameter to force your script into the footer. Putting your script into the footer just before the closing body tag prevents it from blocking the page rendering.

Google’s PageSpeed Insights tool will advise you of any scripts that might be blocking rendering because they appear within the <head></head> element.
You may well do the right thing, but unfortunately with WordPress, you’re at the mercy of every other developer who’s plugins you may use. Should one of your plugins include its script in the head, and should that script rely on a function library, such as jQuery then WordPress will helpfully pull jQuery up into the head so the script doesn’t fail. Only now you have the jQuery library blocking rendering of your page. Even if you specified that jQuery be inserted into the footer, any errant plugin can ruin your plans.

So, what can you do? You can try installing another plugin to try and fix it for you (I’ve tried this with limited success) ,or you can hack the plugin. The problem with the latter approach is you’d have to redo it every time the plugin was updated, so I’ve worked out my own solution.

The wp_register_script and wp_enqueue_script functions both accept the $in_footer parameter and if you look at the code for those functions you’ll see it calls an internal WP method that adds some meta data to the script handle.

Using this method it’s possible to add the same meta data to any script handle you like, whether its in a plugin or not.

Step 1

Assuming you’re using jQuery dependent scripts, and you’ve set jQuery to be in the footer, but it’s not, examine the script tags in your head element and find the first one that isn’t part of the jQuery library. Search for the script filename within your site’s codebase.

Step 2

Having found where the script is registered or enqueued, the handle will reveal itself as the first parameter of the function call. e.g. foo_script

Step 3

Create a new function in your functions.php file, I’m calling mine “rr_force_plugin_js_to_footer”. Then use add_action to call your function. I’m not sure which is the most appropriate action on which to hang the function call but init seems to work. Your code should look like this


add_action( 'init', 'rr_force_plugin_js_to_footer' );

function rr_force_plugin_js_to_footer(){
$wps = wp_scripts();
$wps->add_data(‘foo_script’, ‘group’, 1); // repeat this line per script
}

Step 4

Work your way through each of the blocking scripts and add a new line to the function, just changing the handle you find each time. You’ll know when you’re done when the jQuery library scripts drop to the bottom of the page where you want them.

YMMV.