Every time I register a script and add jquery as dependency, it gets
added to the <head>
in the finally rendered HTML page. As this
blocks page rendering time – the included script might modify the DOM
– I want to add it to the end of the page to prevent this behavior.
This will make Google happy and positively influence my page rank as
page loading time should decrease.
class RegisterScripts
{
public function __construct()
{
add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) );
}
public function scripts()
{
wp_enqueue_script(
'requirejs',
get_stylesheet_directory_uri().'/assets/scripts/vendor/requirejs/require.js',
array( 'jquery' ),
filemtime( plugin_dir_path( __FILE__ ).'assets/scripts/vendor/requirejs/require.js' ),
true
);
}
}
So what does core do then? Actually it’s quite easy. The WP_Scripts
class is an extension for the class WP_Dependencies
. And when you
make a call to wp_enqueue/register_script()
, it just uses the
add_data()
method from there.
$wp_scripts->add( $handle, $src, $deps, $ver );
if ( $in_footer )
$wp_scripts->add_data( $handle, 'group', 1 );
As you can see, it adds “data” with the script name as a first
argument and sets some group to 1. This just tells the class where to
put the the script data in the global array. Then, when looping
through the array, WP just checks the current hook and prints either
the default part or, in case of the end of the page, the wp_footer
hook, all scripts that have a group equal and/or higher than 1. That’s
it.
Now to the part where we quickly fix that:
// Move jQuery to the footer
global $wp_scripts;
$wp_scripts->add_data( 'jquery', 'group', 1 );
Of course you can do that with every other script as well. A (maybe
incomplete) list of default scripts can be found in
Codex. If you want to have the real list, you’ll have to dump
$GLOBALS['wp_scripts']
and look through the array. In case you want
to wrap all this up in a standalone plugin, you of course can do. I
recommend using a mu-plugin.
/* Plugin Name: jQuery to the footer! */
add_action( 'wp_enqueue_scripts', 'wcmScriptToFooter', 9999 );
function wcmScriptToFooter()
{
global $wp_scripts;
$wp_scripts->add_data( 'jquery', 'group', 1 );
}
Keep in mind that there might be plugin or theme scripts doing things
wrong(!) and this solution might break. Normally this would happen if
the custom scripts are loaded into the header or if the whole WP
Dependency API is bypassed and the script hard coded. Conclusion: Test
before you add that mini plugin to an already live page. If it doesn’t
work, inspect where and how the script loading works. Then fix that
and try to load those blocking scripts to the footer as well. Google
will love you.
If you want to go further, here’s a related recommendation. If you
want to create JavaScript classes, take a look at
JavaScript++.