How to move jQuery script to the Footer

As default, WordPress actions put the jQuery scripts in the header of all HTML pages however, sometimes it is necessary to move these scripts to the footer of the page but a simple movement is impossible. As jQuery script (and dependents) is defined by WordPress during the first steps of its loading, when you try to redefine later its output through wp_enqueue_script( ..., $in_footer TRUE ) or similars, you haven’t got any result.

Designing a new feature, with jQuery!

There are some methods to make this change, some more risky, others more conservatives. Today, I’m going to show two methods very simple and quite conservative based on just one function. It’s all you need.

First method

The first method is based on changing the array var $extra[] of some elements of the array registered[], that’s one of the properties of the class WP_Scripts. In our case, we’re going to add a new element called group to the array $extra[] that’s included in all elements of the array registered[]. See one the example of the class WP_Scripts

class WP_Scripts $wp_scripts {

    Any $property_1
    Any $property_2
    ... // Some other properties

    Array $registered {
        'element_1 => Array {
              string $handel
              string $src
              ... // Some other vars
              Array $extra {
                  Int $group
             }
        }

        'element_2 => Array {
              string $handel
              string $src
              ...
              Array $extra {
                  Int $group
             }
        }

        ... // etc.

        'element_n => Array {
              string $handel
              string $src
              ... // no extra for this script, for example
        }

    }
    ... // Some other properties

}

For doing this, as the array registered[] is accessible by a named key, we can use a very simple function, something like that:

<?php
function send_jQuery_in_footer () {
    global $wp_scripts;
    $wp_scripts->registered['jquery']->extra['group'] = 1;
    $wp_scripts->registered['jquery-core']->extra['group'] = 1;
    $wp_scripts->registered['jquery-migrate']->extra['group'] = 1;
}
add_action ( 'wp_head', 'send_jQuery_in_footer', 1, 0 );
?>

With this simple function we do actually change the behaviour of the output because all the elements related to the jQuery module are marked as in_footer, ie, group = 1.

See that it’s not enough redefining just jQuery script. After all, the WordPress jQuery script is just a trigger empty script for enqueueing jquery-core and jquery-migrate –the real scripts– so, if these two last scripts are not redefined too, then jQuery will keep in header because of this, it’s necessary to change the value for the three scripts: jQuery, jQuery-core and jQuery-migrate.

By the way, it’s always better, if you write this little function, to add a if ( ! is_admin() ) before the action because we don’t want to interfere with the WP admin interface so the final code would be like.

<?php
function send_jQuery_in_footer () {
    global $wp_scripts;
    $wp_scripts->registered['jquery']->extra['group'] = 1;
    $wp_scripts->registered['jquery-core']->extra['group'] = 1;
    $wp_scripts->registered['jquery-migrate']->extra['group'] = 1;
}
if ( ! is_admin() ) add_action ( 'wp_head', 'send_jQuery_in_footer', 1, 0 ); ?>

This is the basis of the change, to add the var group and set it up to 1, for moving each one of these scripts to the footer of the page.

Refining the function

But now, instead of dealing directly with $wp_scripts->registered[] array –it’s always dangerous–, we’re going to use the correct way for changing the properties of any script element of this array using the method add_data() included inside the class WP_Dependencies. So, the final function will be this next:

<?php
function send_jQuery_in_footer () {
    global $wp_scripts;
    $wp_scripts->add_data( 'jquery', 'group', 1 ); // Instead of $wp_scripts->registered['jquery']->extra['group'] = 1; ...etc
} 
if ( ! is_admin() ) add_action ( 'wp_head', 'send_jQuery_in_footer',  1 , 0 ); // Take a look to priority
?>

Just one more litle thing, don’t forget to fix the execution priority to 1 for the function send_jQuery_in_footer inside the WP action wp_head otherwise, the function will arrives late and the output of the jQuery scripts will have been already done inside HTML head.

Remember, the default WP priority 10 doesn’t work; it has to be 1.

Second method

This second method is, perhaps, less conservative because it avoids the loading of the WordPress original jQuery script, in fact, two files (jQuery-core and jQuery-migrate) and loads the public version jQuery file hosted by Google. In most of cases, it’s actually the same but, sometimes there is a little variation related with the version of jQuery and, of course, jQuery-migrate is not loaded. In any case, it’s also a good method and also puts the jQuery on the footer.

In this method, first we completely deregister the WordPress original jQuery script, and then we register and enqueue a new version of the jQuery. The second method is also just one function.

<?php
function reassign_jQuery() {
     wp_deregister_script( 'jquery' );
     wp_deregister_script( 'jquery-core' ); // do not forget this
     wp_deregister_script( 'jquery-migrate' ); // do not forget this

     wp_register_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js', array(), '1.12.4', TRUE );
     wp_enqueue_script('jquery'); 
} 

// Now you can load all of your jQuery dependent scripts, probably you'll prefer to add a priority actions checking 
if ( ! is_admin() ) 
     add_action('init', 'reassign_jQuery'); 
?>

Although this method is the most widespread and famous –you can easily find a lot of similar examples on the web–, I’ve preferred to talk about it in second place for two reasons that I personally consider relevant:

  • As there is not an URL hosted by Google that effectively always points to the latest version of jQuery, in time, we’ll have to check (and sometimes to correct) the number of the latest jQuery file.
  • Additionally, perhaps the time load of your theme increases on the opinion of speed test engines because they see that your theme need one more additional external resource.

Perhaps, you think that to include the version number inside the code is not a problem… And probably it’s right if you don’t have 50 WordPress client installations working with several themes… So, I advice you to think a little about your current installations before to choose this second method. It works but it can to need a lot of maintenance.

A final thought

Before doing this change (with any of these two method), please, firstly check the behaviour and structure of the rest of the installed scripts by your theme because, if one of them works thanks to –for example– little inserted script code in the HTML tags (div, spans, etc, ) then the change of jQuery position will not be possible, or you must also change the behaviour of the rest of dependent scripts.

Always it’s complicated to move jQuery from to top to bottom, but it’s not impossible. If you have got time load issues for example, you probably ought to do it but, this movement is very structural because the behaviour of all web page components is affected so, you just need to do the changes step by step, and also check each one of these changes individually. If you work slowly, you get it.

Have a nice WordPressing!

5 Comments on How to move jQuery script to the Footer

Leave a Reply to Joan Miquel Viadé Cancel Replay

   Mandatory field
You can use these HTML tags inside the commment.
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>