Topic For Discussion: jQuery
The Theme Review Team is considering guidelines regarding handling of jQuery (and any other scripts bundled with and registered by WordPress core) by Repository-hosted Themes. We would like to gather input and feedback on the following discussion points:
- The first point for discussion is that Themes should always use the current version of jQuery as bundled with WordPress, so as to avoid core/Plugin breakage due to an unexpected version (whether older or newer than the WordPress-bundled version).
- The second point for consideration is that, if Themes should always use the current version of jQuery as bundled with WordPress, then Themes should not bundle their own version of jQuery, and should instead enqueue the core-bundled version, via wp_enqueue_script( ‘jquery’ ).
- The third – and likely, most controversial – point for discussion is that Themes should not deregister the core-bundled jQuery, in order to register a CDN-hosted, minified version of jQuery, as such functionality is better-left to the end user, via Plugin.
Note that Themes are currently already required to enqueue any custom scripts via wp_enqueue_script(), and to hook such scripts in wherever appropriate (primarily, either wp_head or wp_footer).
So, what are you thoughts on the above discussion points? What else do we need to consider, regarding handling of jQuery and other WordPress core-bundled scripts?
Michael Fields 8:47 pm on March 1, 2011 Permalink
I completely agree with all three points and honestly, there is nothing that I would add or remove.
Otto 8:49 pm on March 1, 2011 Permalink
Absolute yes to all three.
If a user wants to use a CDN version of jQuery, that’s absolutely plugin territory. Use-Google-Libraries is my choice there.
Also, I would expand that to include *any* WP-included JS library. WordPress tries to avoid “breaking” changes, which is why jQuery 1.5 was not included in 3.1 (also, timing was bad).
I would also like it if it was a recommendation that themes enqueue-ing their JS files would do it in the proper place, namely on the wp_enqueue_scripts or admin_enqueue_scripts action hooks. It does work on init and in several different hooks, but the wp_enqueue_scripts hook is really the better place to do it. For admin page-specific JS enqueues, there are also page-specific hooks that can be used as well.
Chip Bennett 9:08 pm on March 1, 2011 Permalink
We would definitely want to extrapolate such guidelines to *any* WordPress core-bundled scripts. jQuery is merely the most frequently encountered.
Chip Bennett 9:54 pm on March 1, 2011 Permalink
I’ll be sure to start using those as the recommended/required hooks into which to hook enqueued scripts. I think that easily fits into proper support/implementation of core WordPress functionality.
Otto 7:49 pm on March 3, 2011 Permalink
Since somebody asked, the admin_enqueue_scripts action actually gets the $hook_suffix parameter passed to it. You can use that to determine which admin page you’re on and act accordingly. Like so:
add_action(‘admin_enqueue_scripts’,'example’);
function example($hook_suffix) {
// $hook_suffix will be the page name or other hook information.. examine it to see what it contains where and you’ll figure it out soon enough
}
Emil 9:12 pm on March 1, 2011 Permalink
Definitely in agreement to all 3 here as well.
Another suggestion is when you use custom JS library please don’t minify and/or pack the source and don’t remove header notes, original author, copyright etc. I have seen JS files that are not GPL compatible (and yes most of them usually are) and also JS authors who strictly forbids the distribution via Themes/Templates.
This would be an example: (picked randomly)
http://themeforest.net/item/javascript-showcase/74131
If you take a look you will see two types of license, personal and extended and only the extended allows you to use the codes in projects such as Themes. Personal version does not.
This is probably bit beyond the jQuery, but it’s connected with, so…
esmi 9:14 pm on March 1, 2011 Permalink
No arguments about any of the above from me.
Greenshady 9:14 pm on March 1, 2011 Permalink
Themes should always use any script that’s included with WordPress. They should not be bundling their own versions of these scripts or linking up to a CDN. This breaks plugins if there’s a conflict between versions.
WordPress is the framework we’re all building on top of. Not using the WP-bundled scripts is a prime example of not playing nice with others.
Now, if a *user* wants whatever extra optimization from registering their own version of the script, that’s plugin territory.
Joachim Kudish 9:18 pm on March 1, 2011 Permalink
Likewise, going to agree with all of the above.
Satish Gandham 9:19 pm on March 1, 2011 Permalink
agree with all three.
curtismchale 9:21 pm on March 1, 2011 Permalink
All good items for themes on the repository. Regarding minified versions of scripts, I don’t think that there should be a prohibition on using the minified versions but maybe a requirement that you also include the non-minified version with the license intact for reference.
Emil 9:47 pm on March 1, 2011 Permalink
well no, because we need to unpack to see what’s behind the source, not many will include dev version for that and if i.e. we use http://dean.edwards.name/packer/ who can tell what’s what
Chip Bennett 9:50 pm on March 1, 2011 Permalink
Our thinking is that swapping out the WordPress core-bundled jQuery for a minified version is Plugin territory, because the user should be considering the impact not only to the Theme, but also to core, and to any installed Plugins. Besides, Plugins can handle such functionality much better (consider the minification functionality of the various caching Plugins).
curtismchale 10:11 pm on March 1, 2011 Permalink
Yes I agree that they shouldn’t be swaping out the bundled jQuery for a minified one but if there is a slideshow plugin I don’t see an issue with using the minified one and including a non-minified one.
@Emil just require with theme check or the approval process that they include the non-minified version.
Chip Bennett 10:14 pm on March 1, 2011 Permalink
I think the most ideal approach there would be to register a CDN-version (i.e. from Google) for the required script.
I think that actually bundling a common JS script with the Theme itself should be a last-resort measure.
Emil 10:49 pm on March 1, 2011 Permalink
That would be good idea.
curtismchale 6:15 am on March 2, 2011 Permalink
Fair enough
scribu 10:21 pm on March 1, 2011 Permalink
I would just like to point out that the bundled version of jQuery is already minified:
http://core.trac.wordpress.org/browser/branches/3.1/wp-includes/js/jquery/jquery.js
Chip Bennett 10:26 pm on March 1, 2011 Permalink
Well that rather settles that particular debate.
Emil 1:29 am on March 3, 2011 Permalink
Correct minified, but not packed there’s a huge difference in that
Otto 11:01 pm on March 1, 2011 Permalink
To clarify Emil’s point, if somebody includes a packed script named script.js and an unpacked one named script.dev.js, what evidence do you have that the packed script doesn’t have one extra line of code in it somewhere that allows a backdoor access to the site in some manner?
I’d be pro-banning minified/obfuscated code of any sort in the themes directory. If a user wants to minify, they can after the fact.
Emil 1:30 am on March 3, 2011 Permalink
thank you Otto
sabreuse 9:30 pm on March 1, 2011 Permalink
Agreed on all 3 points.
Jacob 9:45 pm on March 1, 2011 Permalink
I would like to add a point about where scripts are loaded; head vs footer. At the very least, plugin authors should use a standard way to change where scripts are hooked.
Daniel 9:51 pm on March 1, 2011 Permalink
The correct hook to enqueue scripts is wp_print_scripts. This fires before wp_head and after wp_print_styles and is hooked itself to wp_head. From a point of view of correctly loading dependensies and priorities, this is the correct hook, not crowding them in wp_head
Otto 11:05 pm on March 1, 2011 Permalink
wp_enqueue_scripts is the correct hook, actually. There’s a whole function for it, hooked to wp_head with a priority of 1. Hooking them here ensures they’re enqueued first. Hooking to wp_print_scripts works, but really makes little sense, as that is enqueueing them at the last possible minute and making order matter for cases where scripts might need to be dequeued.
Enqueue in wp_enqueue_scripts.
If you have to dequeue, do it in wp_print_scripts.
Seth Merrick 9:53 pm on March 1, 2011 Permalink
While I agree with all 3 points in principle, I’d like to point out the other side of the coin:
Every major WordPress Release ( 3.x vs. 3.x.x ) should come bundled with the latest stable version of jQuery & jQuery UI! It’s absurd that it took until 3.1 to get past jQuery 1.4
Though I would have preferred not to, I once had to deregister core jQuery and enqueue the latest version in a theme in order to implement a feature that was dependent on the latest jQuery UI which, at the time, was only compatible with jQuery 1.4 or later.
Chip Bennett 10:12 pm on March 1, 2011 Permalink
From what I understand, jQuery 1.5 was causing breakage issues in WordPress 3.1, which is why jQuery 1.4.4 was included.
Downstream projects almost always have such version-delay issues, because new versions of upstream projects have to be tested thoroughly before being bundled. So, if Themes were to start bundling jQuery 1.5, and deregistering version 1.4.4, currently we *know* that it would result in certain breakage.
Seth Merrick 10:20 pm on March 1, 2011 Permalink
I’m satisfied with the upgrade to 1.4.4 instead of 1.5. In fact, I’m pretty sure 1.5 hadn’t dropped until after the 3.1 code had been frozen.
I would say it comes down to a matter of prioritization. As it stands now, this issue seems to be of a lower priority than I’d prefer. Of course, every developer would like to see their own ‘pet issue’ at the top of the list, and I understand there may be more pressing matters at hand.
Saying “the latest version of jQuery causes breakage” is really saying “fixing the breakage caused by the latest version of jQuery was not of sufficient priority to make the cut.”
I think that as WordPress Themes and Plugins continue to increase in complexity, and interfaces become more robust and reliant on jQuery, this issue will garner more attention in the community, hopefully becoming more visible as the team sets milestones for future releases.
Andrew Nacin 10:20 am on March 3, 2011 Permalink
Yes, that’s accurate — 1.5 hadn’t dropped until 3.1 was frozen.
Potentially, yes, that would be our reasoning. At the same time, it’s not just breakage, it’s testing. There are quite a bit of jQuery bits to test, and if a major jQuery release isn’t in trunk long enough, we’ll miss something. Just one issue with the widgets panel could affect hundreds of thousands of users. That’s no fun.
That said, that wasn’t our reasoning here. While our code was indeed already frozen, it’s not that 1.5 broke any of our JavaScript. It’s that 1.5 majorly broke jQuery UI (oops!).
Had it been a minor 1.4.x release, we probably would have updated it after a thorough review of the changes.
You have a point that it comes down to prioritization, but we’ve discussed this and we made it a much higher priority during the 3.1 cycle. At one point we were running jQuery trunk in WordPress trunk. We’ll be putting 1.5.2-dev in core the moment we start 3.2 development.
Emil 9:57 pm on March 1, 2011 Permalink
@Chip agreed, sorry could not reply directly, there’s a some kind of error when I press the “Reply” button.
Brian Krogsgard 9:59 pm on March 1, 2011 Permalink
Well, I’ll play devil’s advocate.
I have a hard time thinking of any reason #1 and #2 are bad ideas. It might be fun to use 1.5, but I totally understand that is probably a limited use case and can be handled by advanced users that would likely want to use it.
As far as #3, it’s well and good to say it’s plugin territory, but is it really? I mean, it can be, but a lot of users will never know they can speed their site using such a plugin, and won’t do so. Whereas, if a theme author can deregister, and register from Google, and it helps optimize the theme, what’s the harm in that if it’s done properly?
I’d rather just see a recommendation for a standard method of doing so, rather than not allowing it. It just feels a bit too restricting.
Chip Bennett 10:10 pm on March 1, 2011 Permalink
That’s why we’re having the discussion: to make sure that we hear, and try to understand, all points of view.
I’m curious: what is the actual performance gain from using a cached, minified, CDN version of jQuery, rather than the WordPress core-bundled jQuery?
There is another problem with handling this sort of thing in the Theme: WordPress updates – specifically, when WordPress updates, and the Theme doesn’t. Suddenly, the Theme is introducing breakage issues, due to core or Plugins expecting one version of jQuery, and the Theme registering a different version.
With respect to Repository-hosted Themes, we have to balance what is best, and most appropriate, for the widest public audience. This sort of discussion helps us better understand what meets those criteria.
Brian Krogsgard 10:20 pm on March 1, 2011 Permalink
Basically, the way it was put to me, was in the form of a question:
“Are your servers faster than Google’s?” I’m not the smartest developer, but that seemed logical enough to me.
As far as preventing old versions of jQuery in older themes, that could be part of the recommended way of implementing it , include a check that makes sure the jQuery version is at least as up-to-date as the WordPress bundled one.
Seth Merrick 10:22 pm on March 1, 2011 Permalink
I think an even better question along the same lines is “Is your browser’s cached version of the Google CDN jQuery faster to load than making another request to your private server?”
Chip Bennett 10:28 pm on March 1, 2011 Permalink
The issue isn’t that the Theme registers the same version of jQuery as WordPress at the time the Theme is approved, but rather, what happens when WordPress is updated, but the Theme isn’t.
(A quick look around the Repository should give a good indication of how infrequently the vast majority of Repository-hosted Themes are updated.)
Brian Krogsgard 10:33 pm on March 1, 2011 Permalink
That’s why I said to do the check. If the version isn’t at least the latest version bundled with WordPress, then use the WordPress version.
Brian Krogsgard 10:34 pm on March 1, 2011 Permalink
Sorry, misread your comment…
robertjakobson 12:32 pm on March 7, 2011 Permalink
The best way is to call Google libraries by default and if they are not available then use the scripts bundled with WordPress.
Otto 9:39 pm on March 2, 2011 Permalink
“As far as #3, it’s well and good to say it’s plugin territory, but is it really?”
Yes, absolutely.
Consider the case where somebody is using WP for an internal site in a company, and the viewers of the site don’t have general internet access. It would kinda suck if somebody installed a theme and now the thing was broken because the theme tried to use links to Google’s jQuery, which nobody in the company can access.
Themes should be themes, period. They should be about the design and layout of the site. When themes start trying to provide functionality, things get weird and start breaking.
Let the users decide what functionality they want. Don’t let theme designers try to decide it for them.
robertjakobson 12:31 pm on March 7, 2011 Permalink
Obviously one uses a fallback – if google libraries are available then use them, if not then use the WP bundle. A moot point!
Daniel 10:12 pm on March 1, 2011 Permalink
If for whatever reason themes do change the provided jQuery version, it should do it in an if( ! is_admin() ) conditional, or else the sections of the heavily jQuery powered backend, like the file uploader, may collapse.
Seth Merrick 10:25 pm on March 1, 2011 Permalink
This raises a major pet peeve of mine: When plugin & theme developers load their scripts and styles willy-nilly on ALL admin pages and/or the ENTIRE front end instead of only loading them in the appropriate contexts.
Nothing makes me nuttier than providing support to a user who is having problems with my plugin or theme because another developer loaded their junk into my admin page!
Chip Bennett 10:36 pm on March 1, 2011 Permalink
Yep; this is part of what we’re trying to make sure we handle properly, also, by pointing developers to the correct way to enqueue scripts, and the correct hooks into which to hook them.
Devin 10:45 pm on March 1, 2011 Permalink
Agreed on all three points.
StandardSpace 11:57 pm on March 1, 2011 Permalink
Agree with all three. It’s a pain removing duplicate copies of wordpress churned out by themes and plugins. I just want to CDN and fallback to local using functions.php
StandardSpace 11:58 pm on March 1, 2011 Permalink
Should have read “duplicate copies of jQuery”
visaap 7:19 am on March 2, 2011 Permalink
Three thumbs up!
Ben Huson 12:05 pm on March 2, 2011 Permalink
Definitely agree with all 3 points.
Andrew Nacin 10:21 am on March 3, 2011 Permalink
+1 from me.
Paul 3:06 am on April 29, 2011 Permalink
/**
*/
add_theme_support(‘use-google-super-faster-jquery-cdn’);
Chip Bennett 3:07 pm on April 29, 2011 Permalink
None of us disagrees with the advantages of using Google’s CDN for such resources; however, the consensus appears to be that the decision to replace core scripts with CDN is an individual user decision, and thus “Plugin” Territory.