How to enqueue the bundled jQuery in footer – The Right Way

Why scripts should be placed into the footer of a site:

With scripts, progressive rendering is blocked for all content below the script. Moving scripts as low in the page as possible means there's more content above the script that is rendered sooner.

The second problem caused by scripts is blocking parallel downloads.

Steve Souders in „High Performance Web Sites: Rule 6 – Move Scripts to the Bottom

WordPress comes with many bundles JavaScript libraries like jQuery or jQuery UI.
So plugins and themes doesn't need to bundle these libraries again, instead, they can use the WP_Scripts API.

The registration is controlled by the function wp_default_scripts() in /wp-includes/script-loader.php.

/**
 * Register all WordPress scripts.
 *
 * @since 2.6.0
 *
 * @param object $scripts WP_Scripts object.
 */
function wp_default_scripts( &$scripts ) {
// […]
	$scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array('prototype'), '3517m' );

	$scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array('utils','jquery'), false, 1 );
// […]
	// not used in core, replaced by Jcrop.js
	$scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop') );

	// jQuery
	$scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.7.2' );

	// full jQuery UI
	$scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui/jquery.ui.core.min.js', array('jquery'), '1.8.20', 1 );
	$scripts->add( 'jquery-effects-core', '/wp-includes/js/jquery/ui/jquery.effects.core.min.js', array('jquery'), '1.8.20', 1 );
// […]
}

As you can see, WP_Dependencies->add() expects the following arguments: The name, the path, the dependencies, the version and last but not least the argument to enqueue the script either in header or footer. Same as for wp_register_script() or wp_enqueue_script().

Now you should have noticed that the jQuery registration doesn't have the last argument, which means the script will be enqueued in header. With the help of a filter inside the wp_default_scripts() function we can change this.
In practice:

<?php
/**
 * Plugin Name: Enqueue jQuery in Footer
 * Version:     0.0.1
 * Plugin URI:  http://wpgrafie.de/836/
 * Description: Prints jQuery in footer on front-end.
 * Author:      Dominik Schilling
 * Author URI:  http://wpgrafie.de/
 */
function ds_enqueue_jquery_in_footer( &$scripts ) {
	 
	if ( ! is_admin() )
		$scripts->add_data( 'jquery', 'group', 1 );
}
add_action( 'wp_default_scripts', 'ds_enqueue_jquery_in_footer' );

This a really clean and nice way. No need of deregister and register functions.

Of course, you should test if this breaks any functionality, especially when you are using plugins/scripts which hasn’t set dependencies correctly.

Comments are closed.

5 comments

  1. Konstantin Kovshenin

    That is also a nice way to break other scripts which rely on jQuery, introducing the nasty flicking effect, late animations and even Javascript errors if the relying script hasn't set dependencies correctly (i.e. depending script loaded in header while jQuery loaded in footer).

    With scripts, progressive rendering is blocked for all content below the script. Moving scripts as low in the page as possible means there's more content above the script that is rendered sooner. The second problem caused by scripts is blocking parallel downloads.

    You can serve your scripts from a different domain or subdomain instead, which allows parallel loading. Same applies to stylesheets.

    Cheers, and use with caution!
    ~ Konstantin

  2. Dominik

    Konstantin, thanks for your comment.

    Of course, you should test all things before you use them in production.
    I also thought about a note, but forgot to add it to the post. Now added.

  3. Anna L.

    Oh! So simple... Personally I prefer to deregister bundled jQuery at all, but actually it's not always needed...
    Thank you very much for sharing

  4. kaiser

    @Dominik It's not too hard to check which scripts inside the $wp_scripts global has jquery as dependency - and then move these to the footer too. +1 from my side.

  5. Gerald

    I agree with Konstantin.
    handling jquery scripts properly is no rocket science but it will take quite a while till most plugins\themes are using the wp_enqueue_style function correctly.
    so as you mentioned - testing compatibility is mandatory.