How to Defer Parsing of Enqueued JavaScript Files in WordPress

If you’ve ever measured your site’s page speed with tools such as Google’s PageSpeed Insights or GTMetrix, you may have seen a message suggesting that you “reduce or eliminate render-blocking Javascript in above the fold content”. One way to do this is to defer the loading of those scripts until after the page has loaded. 

How to Defer Parsing of Enqueued JavaScript Files in WordPress

In WordPress, any Javascript files should be properly enqueued by using the wp_enqueue_scripts action hook and wp_enqueue_script function in your functions.php file.

function mind_load_these_here_scripts() {
    wp_enqueue_script('cycle', get_template_directory_uri() . '/js/cycle.js');
    wp_enqueue_script('magnific-popup', get_template_directory_uri() . '/js/magnific-popup.js');  
    wp_enqueue_script('script', get_template_directory_uri() . '/js/main.js');  
  }

add_action('wp_enqueue_scripts', 'mind_load_these_here_scripts');

Deferring a typical Javascript file is simply a matter of adding defer=”defer” to the Javascript file. Since we can’t do this by using wp_enqueue_script, we’ll use the script_loader_tag filter hook. 

The key is to get the handle for each of the enqueued files and add it to the $defer array. In the wp_enqueue_scripts example above the handles would be ‘cycle’, ‘magnific-popup’, and ‘script’. This script will parse specific Javascript files and add that defer=”defer” to the file before it is output to the page.

function mind_defer_scripts( $tag, $handle, $src ) {
  $defer = array( 
    'magnific-popup',
    'cycle',
    'script'
  );

  if ( in_array( $handle, $defer ) ) {
     return '<script src="' . $src . '" defer="defer" type="text/javascript"></script>' . "\n";
  }
    
    return $tag;
} 

add_filter( 'script_loader_tag', 'mind_defer_scripts', 10, 3 );

How to Find the Handle of Other Scripts

If you need to find the handle of other scripts that may have been added by plugins, etc, you can do so by using the $wp_scripts global variable. This clever little script will output a list of all the script handles, including those loaded by any installed WordPress plugins. Note: You probably only want to use this in a test environment as it will output the handles in the <head> tag and you may see them output to the screen. If not, you can find them by using your browser’s web dev tools or by viewing the source code. 

function mind_detect_enqueued_scripts() {
  global $wp_scripts;
  echo "Handles: ";
  foreach( $wp_scripts->queue as $handle ) :
    echo $handle . ', ';
  endforeach;
}

add_action( 'wp_print_scripts', 'mind_detect_enqueued_scripts' );

What About jQuery?

You want to be very careful if you defer jQuery. Many Javascript files, plugins, etc. depend on jQuery to be available to work properly. If you are trying to run scripts that need jQuery before jQuery has been loaded, your scripts aren’t going to work. Note: The handle for the version of jQuery loaded in WordPress by default is ‘jquery-core.’

To make sure your enqueued scripts are loaded after jQuery, add jQuery as a dependency when running wp_enqueue_script.

For example: 

wp_enqueue_script('cycle', get_template_directory_uri() . '/js/cycle.js', array('jquery'));

When you defer the loading of your Javascript files, you should see improved page speed scores.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.