WordPress: Loading jQuery correctly

Reducing the weight of a website’s resources has become an obsession for some of us, the practise of decreasing the time it takes for a website to load not only keeps our users happy but is known to be a factor in a site’s Google ranking and improve conversion rates.

Only a short while ago I noticed a problem in the way I was handling jQuery in WordPress. To start with I noticed jQuery was being loaded twice, and then after attempting to fix the problem some of my WordPress plugins lost their JavaScript functionality, this blog post will show you how to properly load jQuery so you can delivery a faster site and maintain WordPress script dependancies.

Note – A new version of this fix is now available.

The problem

So you’re creating a WordPress theme and want to use the latest version of jQuery, you might be inclined to put the following code in your template:

<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.1.min.js"><\/script>')</script>

[aside]The code above has been lifted from the HTML5 Boilerplate, a popular default HTML5 template[/aside]

This is good, we’ve got a protocol relative version of jQuery from Google’s CDN and a fallback just in case. But look what happens, jQuery is loaded twice?

The first instance is in fact WordPress loading a local version of jQuery, output by the wp_head() function of which you’ll find in your header.php file.

The incorrect fix

There are couple of examples out there (here’s one) that suggest the following method of preventing WordPress loading the local version of jQuery.

wp_deregister_script('jquery');

This will remove jQuery from WordPress’ list of scripts and is great for stopping the local version being loaded, but it can also cause some of our WordPress plugins to lose their JavaScript functionality, Contact Form 7 is a good example of a plugin that loses it’s JavaScript, it won’t be able to submit a form using AJAX.

The reason some plugins might not work correctly using this method is because when you register a JavaScript file within WordPress you can specify dependancies that said file relies on, if that dependancy doesn’t exist (has been deregistered, for example) the dependant JavaScript file won’t be included. Look back at the last code example… see where I’m going with this?

The correct fix

Right, to correctly use a different jQuery source we need to remove the local version and introduce our new version to WordPress. We quite like the idea of using the protocol savvy, minified, Googlefied version, here’s the code, pop this in your functions.php file:

function load_jquery() {

    // only use this method is we're not in wp-admin
    if (!is_admin()) {

        // deregister the original version of jQuery
        wp_deregister_script('jquery');

        // discover the correct protocol to use
        $protocol='http:';
        if($_SERVER['HTTPS']=='on') {
            $protocol='https:';
        }

        // register the Google CDN version
        wp_register_script('jquery', $protocol.'//ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js', false, '1.5.2');

        // add it back into the queue
        wp_enqueue_script('jquery');

    }

}

add_action('template_redirect', 'load_jquery');

As well as the original deregister, we’re also discovering the correct protocol to use, then re-queuing jQuery so our script dependancies are satisfied. Now we should be using a decent source for our jQuery, only loading it once and our WordPress plugins can properly use jQuery again.

Note: We have to detect the protocol server side, if the script path starts with //ajax.googleapis.com WordPress will assume it’s path is part of your domain, like this http://mydomain.com/ajax.googleapis.com.

 

Hopefully you’ll find this solution useful, in a very un-scientific test earlier I found about half of WordPress driven blogs from people I follow on Twitter suffered from this issue of loading two versions of jQuery, hopefully with this example we’ll be able to reduce the size of our site and maintain jQuery within WordPress.

As always if you spot a mistake or think something could be don better, don’t hesitate to leave a comment below.

Note – A new version of this fix is now available.