3 Ways to Improve PageSpeed by Moving jQuery to the Footer of a WordPress site.

Here’s how to improve your site’s rating on Google’s PageSpeed by moving render-blocking jQuery to the footer.

If you’ve ever tried to improve a site’s performance on Google’s PageSpeed, you’ve probably seen that one of the “Opportunities” is to “Eliminate render-blocking resources”. These resources are typically CSS and JavaScript files. Usually, it’s not easy to remove/move the CSS resources as this will often result in a FOUC, (flash of unstyled content). However, in most cases, you can get away with moving pretty much all JavaScript to the, as long as you’re not using it to style the content in the viewport (usually this is the “above-the-fold”), so let’s do that!

How to Move Common JavaScript Resources to the Footer

First, let’s look at the most common of JavaScript resources; jQuery. Even though jQuery isn’t as popular as it once was, it’ll be around for the foreseeable future as a vast number of JavaScript solutions are built on top of it. Plus, it’s been baked into WordPress for many years, too!

Here are 3 ways to move it to the footer and the logic used here can be used with other JS libraries, too.

1. Add data to the enqueued scripts

This will add the key/value (group/1) to the jQuery scripts, using WP’s wp_scripts->add_data():

add_action('wp_enqueue_scripts', function() {
    wp_scripts()->add_data('jquery', 'group', 1);
    wp_scripts()->add_data('jquery-core', 'group', 1);
    wp_scripts()->add_data('jquery-migrate', 'group', 1);

2. Dequeue existing scripts and enqueue new scripts

This approach is handy if you want to change the source, such as loading from a CDN:

function enqueue_scripts() {
    wp_register_script('jquery', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js', false, null, true);
add_action('wp_enqueue_scripts', __NAMESPACE__  . '\\enqueue_scripts', 10);

3. Move all scripts out of the head

This way move all JS out of the head and into the footer but feels a little extreme with no granular control:

function remove_js_from_head() {
    remove_action('wp_head', 'wp_print_scripts');
    remove_action('wp_head', 'wp_print_head_scripts', 1);
    remove_action('wp_head', 'wp_enqueue_scripts', 1);
add_action('wp_enqueue_scripts', __NAMESPACE__ . '\\remove_js_from_head');


In my opinion option one is the best fit, as there’s no need to remove the default jQuery and you can keep tight control over which scripts are in the head and which are somewhere else.