This is a topic that has been covered numerous times, including several times on this site, but I still find theme and plugin developers that are either unaware of the negative consequences or simply disregard them. I’d like to talk a bit about why exactly removing the default version of jQuery in WordPress and loading one from elsewhere, such as Google, is terribly irresponsible.
The process of removing the default jQuery in WordPress and making it load from Google looks like this:
1 2 3 4 5 6 7 8 | function pluginprefix_load_scripts() { if ( !is_admin() ) { wp_deregister_script('jquery'); wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.9/jquery.min.js', false, '1.9'); wp_enqueue_script('jquery'); } } add_action( 'wp_enqueue_scripts', 'pluginprefix_load_scripts' ); |
It’s an unfortunately very common practice for themes, and some plugins, to do this. Usually the developer does it because he or she believes they are improving the load times of the site using the theme/plugin, or perhaps they’re gaining access to new features in the latest version of jQuery that isn’t yet available in WordPress core. I’ve seen themes and plugins do this simply because they read a tutorial that said it was the best thing to do.
The big question is: why is this bad?
There are many reasons, and I will touch on each briefly.
1. WordPress Loads jQuery in noConflict Mode
The purpose of noConflict mode is to help ensure there are not compatibility problems between jQuery and other javascript libraries loaded into WordPress. In short, noConflict mode means that the standard $ short cut used in jQuery (and other javascript libraries) is not usable, and must be replaced with jQuery.
As shown by the WordPress codex,
1 2 3 | $(document).ready(function(){ $(#somefunction) ... }); |
becomes
1 2 3 | jQuery(document).ready(function(){ jQuery(#somefunction) ... }); |
or
1 2 3 4 | jQuery(document).ready(function($){ // $ has been declared as a "short cut" to jQuery $(#somefunction) ... }); |
You can also use your jQuery like this (when in noConflict mode):
1 2 3 | (function($) { // $() will work as an alias for jQuery() inside of this function })(jQuery); |
So why is loading jQuery from Google (or anywhere else) bad? It’s bad because it is not loaded in noConflict mode, and that can very often result in error messages, such as this:
Uncaught ReferenceError: jQuery is not defined and Uncaught SyntaxError: Unexpected token <
This kind of error happens because the non-standard jQuery library loaded expects you to write your jQuery like this:
1 2 3 | $(document).ready(function(){ $(#somefunction) ... }); |
instead of the proper (in WordPress) way:
1 2 3 | jQuery(document).ready(function($){ $(#somefunction) ... }); |
Since WordPress loads jQuery in noConflict mode and plugin/theme developers (who are doing it right) rely on jQuery being loaded that way, choosing to force WordPress to use a Google library that is NOT in noConflict mode is hugely irresponsible as it can often result in jQuery errors getting thrown when plugins expecting jQuery to be loaded as default from WordPress are used.
2. Increased Support Load for Other Developers
One of the arguments I often see for loading jQuery from Google (and ignoring the advice of many, many prominent members of the WordPress community) is that "it doesn't cause any problems".
Theme developers (sometimes plugins) often feel it's perfectly acceptable to load jQuery from Google because they have not personally received support tickets indicating there is a problem.
If developers of the themes loading jQuery don't get problem reports, how do they know there is a problem? It's simple: plugin developers get support tickets from users of the theme.
Plugin developers are almost always blamed (by the users) for problems in themes because the plugin is installed after the theme, so when a problem pops up after a plugin is installed, it is naturally assumed that the plugin caused it. When in the case of jQuery conflicts, however, it is nearly always the theme causing the problem. I say it's nearly always the theme simply because plugins that have a need for loading custom jQuery are much further and far between, but that doesn't mean plugins aren't the culprits too.
I have personally spent 100 hours or more on support tickets related to problems caused by themes or plugins loading custom jQuery.
Yesterday a theme developer told me "I have never gotten problem reports about jQuery, so how can it be bad?". He can think that but I know for fact that I (and my support team) have received at least 10 tickets directly related to jQuery conflicts caused by his theme.
It is hugely irresponsible as a developer to assume your code doesn't cause problems simply because you don't get reports of it when other developers are giving you report after report.
3. Themes Should Not Modify Core WordPress Behavior
Another topic that has been discussed at length is whether themes should add functional "features" to (or take away from) WordPress. Here's an article I wrote on it for WP Tuts+.
The key point of the discussion is simply that themes should mostly control the appearance of your site and plugins should control the functionality (e-commerce, custom post types, sliders, etc).
Plugins and WordPress itself rely on jQuery for tons of tasks, which means that when jQuery is modified the hundreds of tasks performed by plugins or WordPress core are also modified. In short, swapping out the default jQuery for a different version is a direct modification of the default behavior of WordPress, and a behavior that plugins rely on (and should be able to rely on).
Themes should never take it upon themselves to try and improve the performance of a site, except to ensure that all queries and layouts in the theme are performant. Attempting to improve performance of plugins or WordPress core itself is something themes have no business doing.
Assuming that your needs in a theme are more important than the needs of WordPress core and thousands of possible plugins is hugely irresponsible. There is a very good reason WordPress ships with its own version of jQuery: all developers can safely rely on it.
4. WordPress Updates the Bundled jQuery Version Frequently
One of the other reasons I've heard for loading your own jQuery is that WordPress doesn't always use the latest version available. This is a fair point, especially if the jQuery you are writing requires a newer version.
Interestingly, this is pretty ironic. Want to know what version of jQuery is almost always being loaded on sites that have conflicts? 1.4.4.
Yes, that's right, 1.4.4 (or other similarly old versions).
So the same developers that are arguing that they need newer versions than WordPress ships with are neglecting to update their code to load the new versions?
This is actually probably not so much because of the developers forgetting to update their versions (sometimes it is), but is more likely because a user of the theme has never updated to the new version that includes the updated jQuery. This is really, really common because users simply don't like to update. They especially do not like to update their theme.
A user is much more likely to update WordPress core than they are to update their theme. Know what happens when WordPress core is updated? jQuery is updated. Know what happens when a theme that loads an old version of jQuery is not updated? Conflicts galore.
The easy way to avoid this problem is to simply not offload jQuery.
5. There is One Good Way to Load Custom jQuery
If you absolutely must use a new version of jQuery, then I implore you to please, please do it only via the Use Google Libraries plugin. This is a plugin that will retrieve the Google libraries you need and load them exactly as WordPress code does (jQuery in noConflict mode for example), meaning that plugins relying on one of the core WordPress scripts will continue to function perfectly fine.
It is trivial to require a plugin in a theme.
There is only one reason a theme should ever need to require a newer version of jQuery, and that is simply if the newer version includes methods used in the theme that do not exist in the current version loaded in WordPress.
[divider]
If you do not believe or agree with any of this, I strongly encourage you to write a plugin that relies on jQuery and release it. Once the plugin has been used by a large number of users, I guarantee you that conflicts with themes or plugins loading their own jQuery will be encountered and you will then fully understand why this is so incredibly frustrating.
6. Addendum: Theme Repositories Do Not Permit Replacing jQuery
Many theme repositories, including the official WordPress.org repository and ThemeForest.net, do not permit themes to replace the default version of jQuery. If you wish to have your theme listed in one of the large, popular repositories, do yourself a favor and don't even try.
What about jQuery-UI?
Same exact story.
wp_enqueue_script(jquery-ui-core);
Done.
Completely and totally agree with this.
I have spent days ripping apart themes that have loaded this, themes that all of a sudden refuse to work without jQuery, because major plugins refuse to work.
It is so frustrating for all concerned, unfortunately a problem is that a client sees a theme that they “like” and go with it, ignorant to the possible issues under the theme.
This requires education, but really the theme developers that do this need the education, as it’s getting to the point that it’s quicker & easier for me to do a PSD 2 WordPress job and recommend a designer rather than get a theme off the shelf and hack it so that it places nicely with WordPress.
Nice
Very informative! I’d been loading jQuery myself after I attended a talk at a Wordcamp that encouraged it. However, I’ll use the Google Libraries plugin from now on.
Really useful: thanks for the heads-up to the Google Libraries plugin ๐
Couldn’t agree more. In my early days making themes I used a tutorial the recommended loading custom jQuery and them the taxonomy boxes in the core post editor were broken. I retraced my steps and found this to be the issue.
Later when setting up a new install, I installed a plugin for a popular WordPress eCommerce solution I had the same issue crop up. I deactivated my plugins one by one and discovered to colprit. I wrote the developer and they issued an update the same day.
Anyone who charges for a plugin owes it to the customer to be responsible and not lazy with their code, if you don’t know any better I understand that, but as you learn from the community for the love of God fix your mistakes.
I don’t think #1 is correct. Loading jQuery without noConflict mode does make
$
available, but it does not prevent you from usingjQuery
.Here’s some example code: https://gist.github.com/evansolomon/e8fda70b6e6dca1378df
Yes, you’re correct, thanks for pointing that out.
This issue is one of the reasons that the Theme Review Team places so much emphasis on the separation of functionality and presentation. A Theme simply cannot know all of the ways that its decisions regarding functionality or content creation will affect user configuration, core, and Plugins.
For Theme developers who claim that replacing the core-bundled jQuery library doesn’t have any adverse impact: show us your unit testing that proves that assertion true. What configurations did you test? What Plugins did you test? What core versions of WordPress did you test?
Wow… this is definitely something new I have learnt today. A lot of the tutorials online encourage the use of jQuery loading from Google (I load the ones that match WordPress’ current versions) but I hadn’t realised there were other implications in terms of plugin compatibility. Thanks for the detailed explanation.
Flick: There’s nothing wrong with using Google’s jQuery, it’s just that a theme shouldn’t be making that decision for you. You, the admin of the blog, should make that decision yourself. And if you decide to do it, then there’s the Use Google Libraries plugin, which does it properly and works with any normal theme.
There is nothing to add here. Not even this sentence.
Yep, you pretty much covered all the bases Pippin.
Unfortunately, it’s users that are caught in the crossfire with this issue. If a naughty theme or plugin sets their own jQuery (the worst is when they hardcode it into the theme’s header), there’s nothing I can tell users of my plugins except to contact the developer of the offending theme plugin, stop using it, or attempt to remove the code themselves (scary!).
Cheers Pippin, you’ve just solved an issue with some jQuery code I got for a simple text rotator as it would only work with an external version of jQuery. I’ve updated the code and it’s working great.
Colin
Disclosure: I’m one of the main Roots developers
Can we get off our high horses and stop using words like “irresponsible”?
You can argue that it might not be a good idea to do it, but it’s not irresponsible.
Frankly, we can do whatever we want and do it by default. No one is forced to use Roots. Our code is available for any developer to view or change and we actively encourage that. We don’t even want people treating it as a framework and keeping it up to date by extending it with hooks or child themes.
And if you really want to argue about what theme/plugins authors are responsible for, I’d argue that making sure there’s no errors or warnings in debug mode should be much higher on the list especially if you’re selling your code reviews as a service. Or making sure you actually develop with debug mode on.
You started with a valid point.
But this is insane.
I agree that calling this jQuery stuff irresponsible is somewhat sensationalist, but your counter argument is just pointless. Of course you can do whatever you want, but obviously some of those things are wildly irresponsible.
Thanks for stopping by. A note I’d like to make: this post was not targeted specifically at Roots, but the discussion I had with one of the other Roots developers did spur my writing of this post.
I have to completely disagree with you about it being irresponsible. The inclusion of non-standard jQuery versions has cost me 100’s of hours of support. Ask Carl Hancock from Gravity Forms; the inclusion of non-default jQuery in themes/plugins has cost them $1000s in support costs.
With those two things in mind, knowingly including non-default jQuery when you (developers in general) know that is causes others problems is worse than irresponsible: it’s nearly despicable. I hate to sound harsh but mitigating the problem and claiming it’s not irresponsible at all is worse than claiming it’s not a problem.
The bottom line is this: users have no idea (or care) what causes the problem, they simply see a problem has occurred so they contact the developer of the last plugin they installed. Knowingly allowing that to happen over and over again is as irresponsible as it can be. Do other developers a favor and take accountability.
As an aside, I think it’s okay for a theme to load javascript from a CDN. WordPress doesn’t have a plugin dependency system, so abstracting that to a plugin puts burden on users. If a theme developer thinks it’s important to load jQuery from a CDN (it’s usually not) then I think it’s valid to choose to do it within the theme.
The only reason (that I can see) that a theme should ever do that is if they rely on a newer-than-default version.
Themes should not be taking it upon themselves to try and improve a site’s performance. Theme’s should never include features to minify scripts / CSS from other plugins, so why is it okay to affect the jQuery other plugins rely on, except when it’s absolutely needed?
This argument becomes harder because WordPress doesn’t have a dependency system. If you’re making a theme and want to do something that’s outside the theme scope, you can either (1) just not do it (2) give users instructions to install some plugins or (3) bundle it with the theme.
There are obviously downsides to each, and I don’t think there’s a strictly best answer.
I think themes should think about performance. Drawing the line between theme-specific performance and general site performance gets pretty blurry, in my opinion.
That is really tricky for sure, and like I said earlier, if the theme needs to do it because of a version dependency, I find that acceptable.
I had to pause for a moment thinking about Pippin calling it “nearly despicable”. Seemed a bit sensationalist to me, as Evan mentioned.
But here’s the reality. The best part about WordPress isn’t the code, it’s the community. It’s an incredible community where, generally speaking, we all learn incredible things from each other and play nicely together. It’s just rad.
But when there are developers in the community who knowingly do things (which are, frankly, not all that necessary) that cause trouble for other developers – that’s pretty lame. When we can probably agree on the reality that time, not money, is our most precious resource – and our actions are costing other people hundreds of hours of their time. We’re not talking about something inconsequential – that’s time we can be spending creating awesome things, hanging out with our families, enjoying the fruits of our labour, etc.
Time is precious – doing stuff that, as a community (not dictatorially), we’ve decided robs other people of their time – on purpose, with no great benefit – to me, that seems pretty despicable, too.
Well said sir.
Can’t reply directly to you Pippin, so:
Yes I realize this wasn’t just targeted at Roots I’m just replying from our point of view. I have no idea what other themes do something similar or why they do it.
Two things:
1. Actually we DON’T know that this causes problems since we haven’t experienced them. You told Ben you would provide examples which you haven’t. Ben has personally made hundreds of sites with Roots and used a wide variety of plugins without issue. The ONLY issue we know about is plugins not working with jQuery 1.9, which is a slightly different issue and they should be using the migration plugin.
Roots is meant to be bleeding-edge so we do what’s necessary to achieve that. We don’t hide that fact or mislead people about what our target use-case is.
2. I wouldn’t take this personally, or have even responded, if it wasn’t for you using words like “irresponsible” and “despicable” (seriously?).
Since you never responded to this before, I’m going to ask again what’s more irresponsible between the following cases:
a) Theme developers doing non-standard WP things yet being very explicit about it and targeting developers who can take care of themselves all while offering it for free
b) Plugin developer who sells himself as an expert and offers code reviews to paying members yet doesn’t even develop with debug mode on and has lots of errors in his code
Like I said before, this shouldn’t be about responsibility. Feel free to make any technical arguments you want.
1. I’ll work on providing examples. That’s a very fair point. I have zero problem with it being bleeding edge, and again, I am not targeting Roots with this. The responses Ben made on Twitter (which I chose not to link to out of respect for Ben) are what prompted this post.
2. If you assume for a moment that there is a confirmed problem, regardless of what it is, and it causes 100s of hours for other developers and you (speaking in general again) decide to disregard that, how is that nor irresponsible? Just humor me for a moment and think about that.
a). That’s perfectly fine in my book.
b). Since you’re obviously directing that at me, please point to how you’ve determined I don’t develop with debug mode on and the code with lots of errors in it. I will never claim that my code is perfect (far from it). Yes I absolutely dev with debug mode (haven’t turned it off in weeks).
I’d like to see these issues? Proof sir?
Which issues specifically?
I’m still relatively unclear on what exactly causes the problem here. As I mentioned further up (aside: Pippin, more nesting in these comments please), the noConflict thing doesn’t make sense to me unless the user is using some other library that tries to use the $ alias and jQuery breaks that library. In either case, the jQuery global is still available (see the sample gist).
The possible culprits seem to be:
* Version mismatch, specifically loading an older version of jQuery
* Not using the enqueue functions, and as a result loading multiple versions on a single page or loading things in the wrong order
* The $ conflict with another library (this seems pretty unlikely these days)
The primary problem is versions and is what I described in point 4 above.
Users (in general) hate to update their themes, so when themes are manually loading specific versions of jQuery it quickly causes version conflicts as they continue to install new plugins that are expecting the newer version included in WP core.
Users are much more likely to update WP core (and thus jQuery to the latest bundled version) than they are their themes, especially if the theme does not have an automatic updater included, which very, very few commercial and non-wp.org themes do.
The vast majority of the conflicts I have run into are from themes running old versions of jQuery. The theme developer may or may not have updated the theme to use the latest, but the main point here is that if they had simply used the core WP version, the problem would never have arisen at all.
Great, thanks. That’s what I was wondering.
Re: Pippin
2. Yes I would admit that it would be irresponsible IF THEY KNEW and did it anyway or continued to do it. But as far as we know, that’s not the case with Roots unless someone tells us otherwise.
b) http://i.imgur.com/irMVb.png Not sure how that would happen if debug mode was on. And really, I’m only bringing this up because of the responsibility issue. Otherwise, I wouldn’t care.
b). That’s perfectly fair but do note that that particular plugin was written more than 2 years ago and never personally used. (Going to fix that right now, anyhow).
If you want to call someone names and base their entire work of of one single 50 line widget, fine, but be gracious enough to at least look at a few other pieces of work. I believe Easy Digital Downloads speaks for itself.
When have I called you “names”? You’ve referred to people to as irresponsible AND despicable.
I referred to the act of ignoring problems as irresponsible, never specific people.
Where was Roots even mentioned in the article?
Stop trolling. I think there’s sufficient number of issues you could be working on Roots right now. There also doesn’t seem to be anything cutting edge in Roots that requires jQuery 1.9.1? Example?
I won’t speak to any issues, but I can clear up the relation to Roots. This post stemmed from a discussion with one of the other Roots developers on Twitter yesterday.
Thanks for writing this, Pippin.
I’ve been guilty of this until today. I didn’t realize it was such an issue if the new version was registered with the same id and enqueued in wp_head.
I’ve just changed all the themes I’m actively developing and will start to go back through some of the older themes I like.
Keep it up!
-Jacob
If the theme is coded as mentioned, what is the best way to change or what code should be used so that it will be coded the right way.
Simply replace it with wp_enqueue_script( ‘jquery’ );
Have to disagree here. Simply put, it’s always good practice to load the jQuery library from Google for one simple reason…speed. In most cases, because it is so common across the web, the library is already loaded in the visitors browser. If a page is 300k, you have just reduced loading by almost 25% as opposed to additionally having to load the library. Not sure who would opt to not take that savings.
Joe, it’s a great idea to load jQuery from google, but the choice is one that should be left to the site operator. It is not a decision the theme developer should be making for you.
If you choose to load jQuery from google, you should always use the Use Google Libraries plugin (as mentioned above).
It’s worth noting that the thing you’re reducing by 25% is the total bytes, which does not make the site 25% faster. There are some sunk costs, so to speak, like parsing JavaScript and CSS, and building the DOM. Those things will not be any faster with jQuery served from Google. You also incur some additional costs, like an extra DNS lookup for Google.
The site will be faster (on the first visit, probably) but nowhere near 25%.
Let’s assume that statement is true (though it may not be):
What is the justification for the Theme, rather than a Plugin, controlling the source of the script library?
From a coding purist’s standpoint, this is also very much an issue with separation of concerns. WordPress, as an application, is responsible for a lot of work – managing the database, loading plugins, pushing data to a browser through a theme. Individual parts of it, though, serve specific purposes.
Plugins manipulate the behavior of WordPress logic.
Themes control the format of content output.
Themes should only be responsible for declaring what scripts they depend on; loading these scripts from an alternate location is beyond the scope of controlling the presentation of content. If a site needs to load jQuery (or any script) from a CDN, that can and should be done through a plugin.
This is a nice idea, but falls apart relatively early in the
functions.php
process.Want a custom query for your theme? That’s going in your theme, not a plugin (or controller). Want to create a custom post type for your theme? That’s going in your theme, not a plugin (or model).
I agree with the spirit of the idea that a theme has no reason to redeclare the location of scripts, but I don’t agree with the idea that a theme developer shouldn’t or can’t be interested in doing that. Until WordPress provides a better way to separate those concerns without sacrificing user experience, I’m not sure it’s fair to prosecute people who choose to combine them.
Ultimately I hate the idea of “persecuting” anyone, but then I also have to seriously consider the amount of support time and money I have lost due to this set of issues. I wouldn’t use the word persecute, but I would strongly advocate encouraging developers to follow the advice and not do this.
Only if Plugin-territory code is in
functions.php
A custom query is a means of defining how content is presented; thus, it belongs in the Theme.
CPTs are the one “gray” area. They belong in a Plugin (a user won’t want to lose generated CPT content just because the active Theme is switched), but a Theme needs to know about a CPT in order to define templates to display it.
My solution to the problem is standardized CPTs: WordPress needs a standard nomenclature for content types, so that any Theme can make use of an “event” CPT, or a “book” CPT, or a “real estate listing” CPT. Then, content generation and presentation can be separated properly, and CPTs won’t represent Theme lock-in.
I actually said “prosecute”, fwiw.
Whoops! Thanks for the correction.
I disagree. A query is what is being displayed, not how it’s displayed. In anything MVC-y you’d never do a query in the view, which I think is clearly what a theme is most like.
I disagree with your standardized custom post type idea, but that’s probably outside the scope of this post. I will say that it seems shortsighted to me to think about every theme as something that has to be transition-able. I think that’s a good approach for things like the wp.org repo, but not for every theme. The unfortunate reality is that there are some things you just can’t do if being able to change themes without losing content is a requirement.
I wish there was a way to truly rely on standardized post type names, but there are a lot of caveats that make it not realistic, but that is another post.
@Chip
Hmm, a standard nomenclature eh? Sounds a lot like… Schema.org!
Sounds a lot like content types to me, and what’s more, with a well defined standard nomenclature.
Granted, my thinking here is _very_ “blue-sky”, but wouldn’t it be cool if WordPress CPTs were intimately related to the types defined at schema.org. There are a number of types already defined for a large number of things we often describe using WordPress CPTs. Things like Books, Movies, Events, Organizations; heck, even BlogPosting, WebPage and MediaObject that map to the WordPress built-in types. And if the type your after isn’t already defined, schema.org vocabulary is extendable.
Andrew Norcross already has a neat plugin for embedding schema.org microdata into a WordPress post or page, but imagine if WordPress CPTs were modelled after the Schema.org types right out-of-the-box, you could get rich microdata markup for free.
I’m just splurting thoughts out here; I have no solid ideas about how you might implement any of this, but maybe it would be possible to gather all the types (and their properties) from schema.org as PHP object interface model. Developers could then implement certain content types however they wanted as long as they implement the proper interface for that type. What’s more, with each CPT being defined as a class, you could make use of object inheritance (following the schema.org type hierarchy) while reducing the risks of function name collisions.
I’ll stop now; I’m getting ahead of myself! Something to think about nonetheless.
I agree with this. I’ve purchased themes for clients only to find errors due to multiple versions of jQuery being loaded. I’ve seen plugins and themes dequeue the core WordPress only to load their own jquery script included in the plugin/theme.
I was about to disagree with it being irresponsible until I read the part about using the Google CDN. This is exactly what we do with any plugin or Theme that we create for our clients and have had no issues.
//Don’t load in the admin area
if (!is_admin()) {
//deregister local jQuery
wp_deregister_script(‘jquery’);
//Register Google Hosted jQuery for speed optimization.
wp_register_script(‘jquery’, ‘http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js’, false, ‘1.9.0’ );
//Enqueue Google Hosted jQuery
wp_enqueue_script(‘jquery’);
//Load Bootstrap.min.js
wp_enqueue_script(‘bootstrap’, get_bloginfo(‘template_url’).’/js/bootstrap.min.js’, array(‘jquery’), ‘2.3’ );
}
Good Post!
The problem with that is the jQuery version being hardcoded. What if the jQuery version you were using had deprecated a function/feature that WordPress was harping in in their version (which could quite possibly be older)? Then – you’d possibly get errors and it would start the cluster of support tickets Pippin normally deals with. Similar to the ‘Use Google Libraries’ plugin users have eluded to, my plugin, WP jQuery Plus http://wordpress.org/extend/plugins/wp-jquery-plus/ also finds the exact version WordPress is loading and then loads that version from Google. Always the same version – just loaded from Google.
Thanks for pointing out your plugin, Zach, I had forgotten about that ๐
Hey Pippin (and everyone) – I just updated WP jQuery Plus to include a local fallback in the event Google’s CDN is down (or if you’re in an area that doesn’t allow Google). It’s done by conditionally adding in the recommended fallback from HTML5 Boilerplate but still has the advantage of loading the exact version as WordPress bundles. Thanks!
Great!
Pippin, first of all thanks for writing a detailed article. I agree with most of your points and I’m also using CDN version of jQuery from Google. Seems like ” Google Libraries plugin” is the best alternative and will try my hands on it.
I agree that themes and plugins made for public use should not do this. However, as an admin of the site, I prefer to use Google Libraries ๐
I am really glad someone is going against that “trend” of using Google libraries .. Unfortunately , reading the comments , I see that many people still think it is a good idea ( why ?? )
There is one point that people do not know about the google libraries, and that qualifies as a very big point against using it , which is that more often than not, those libraries will not load in some countries , primarily – China.
I spend a lot of time in China for work, and because of the google – China dispute, some of the google services are precarious at best and frequently are totally blocked.
This results in totally broken websites , unreadable content , and unusable interfaces , all to the ignorance of the site owner. Now you can always say that China is not a part of your target audience, but (1) : This happened to me also in other countries, and (2) : waiving a third of the world population and the fastest growing internet market in the world is not so savvy in my opinion. I personally witnessed at least 4 cases where US and EU companies had lost a big contract in china due to malfunctioning CDN loads that blocked their websites … and they do not even know it .
( A sidenote – The above said is also true for other google services (like google fonts) and also for other APIยดs like twitter , facebook etc that if integrated into a wp site will result in a loading time of about 2 minutes (until timeout of API request) )
Very good point!
This is not a big deal. If you’re going to be loading jQuery from a CDN you should be adding a local fallback (as seen in HTML5 Boilerplate & explained here: https://github.com/h5bp/html5-boilerplate/blob/v4.1.0/doc/html.md#google-cdn-for-jquery)
If the CDN isn’t accessible or is down for some reason, the local version is loaded and everything still works.
Providing a fallback should definitely take care of that issue.
I always wonder why no one ever brings up closed intranets in these discussions, are they too niche to be considered … or does no one really cares what happens if it does not interact with the inter-webs?!
It’s hard to think of anything more niche for a web developer than developing websites without access to the web. Almost by definition, if you’re going to consider anything too niche to support (and you should probably consider many things to be so) wouldn’t this be one?
Developing with WordPress does not necessarily mean you are developing (only) for websites.
This post is about themes and enqueueing JavaScript. Are those things common outside of websites?
A local intranet could still be using a theme and plugins, so it’s still relevant in my mind.
Yes, it could. I completely agree.
I think that still makes it a website, though perhaps there’s a better name for this that I don’t know about. I also think — and this was my only initial point — that that’s an extraordinarily niche use case.
The question was whether it was too niche a use case to support, to which I think the answer is yes for almost everyone.
That it’s not impossible doesn’t change that.
Evan, using WordPress on a local intranet is not a niche case in the slightest, and you should know better than that. How many internal P2’s do you access on a daily basis? ๐
I have had friends of mine ask me why installing a theme “breaks” their website. On investigation, the website was an internal one in their company, they didn’t have unrestricted internet access, and the theme was doing exactly this sort of thing with the Google libraries. Removing the google code fixed the theme instantly.
Internal websites at companies is a very large market for WordPress and should not be instantly dismissed just because you’re unfamiliar with it.
I think you’re conflating two points here. I left Automattic recently, but to your point, I used lots of internal (private) sites when I was there. None of that had any effect on my browser’s ability to load JavaScript (or anything) from the internet. The internal-ness of a website is not really related to a user’s ability to load content from other websites.
If you think that users without access to the open internet is not a niche use case, then I simply disagree. It’s important to note that “niche” is different than “non-existant”, and due to WordPress’ reach is also different than “not present in large absolute numbers”.
I’d be happy to be proven wrong, but anecdotes are unconvincing. When I was a little kid, my dad used to take me to a place in Chinatown where you could play tic tac toe against a chicken, but I think it would be a mistake to extrapolate theories about chickens and math-based games from that example.
I ran into this exact problem yesterday when migrating a custom plugin to clients site. I was using core jQuery and core jQuery UI. When I migrated everything broke. Long story short after some digging I found that in the function.php file the theme developer had deregistered jQuery and had had registered version 1.4 for all pages outside of the admin.
Completely agree. As the developer of Easing Slider, 100’s of hours have been spent debugging jQuery issues. More-so related to developers loading jQuery through hardcoding the script tag into the header, thus loading it twice (or more). Surprisingly, I’ve almost found that themes purchased from places like Themeforest are the worst for this.
It’s even worse when you’re trying to promote a premium alternative to your plugin. I’ve received some extremely snarky replies from users dissatisfied with their newly purchased plugin not working from the get go. Countless times I’ve been blamed for the terrible coding of others, often having to give refunds to keep everyone happy and avoid nasty feedback publicly. When that’s your livelihood, it’s painful.
Sure, I could prevent this by being bold and completely overriding the jQuery versions being loaded, setting a 999 priority on my action hook and make sure my scripts are loaded in the header first. I don’t, but I could, which would definitely reduce the amount of conflicts occurring. But then I’m a bad developer, encouraging bad practice. A viscous circle, but I guess I can see why some developers do it, especially when money is involved despite it just making the problem worse.
To me, getting continuously blamed for bugs caused by other systems that load / modify jQuery is one of the biggest problems with this. The extra support load is annoying but manageable. Once someone has decided your plugin sucks (due to other’s bad code), it is very difficult to convince them otherwise.
Hi Pippin, nice article and really helpful resource – thank you.
I’m pretty new to plugin development, but one of my plugins is a heavy jQuery user and I have had to learn quickly from my initial mistakes of including jQuery the wrong way. For some reason I find it a tricky issue to get my head around, and there is so many contradicting tutorials and articles on the net it is hard to feel confident that my plugin is doing it in the right way.
Pipping, random thought – have you ever considered setting up a plugin review/consultancy service? I would love to have an experienced plugin developer such as yourself review and critique my work so that I can learn and continue improving it. …much better than launching it and being worried I’m doing things like jQuery the wrong way.
jQuery can be tricky but there is one way to make things really simple: only ever load it with wp_enqueue_script( ‘jquery’ );
If you do that, and have written your jQuery scripts correctly, you shouldn’t ever cause any problems.
You are more than welcome to email me from my contact page if you’d like to get a review done.
Great article man! I rarely read through every single comment, but I did on this on – the back and forth was fantastic. ๐
Thanks heaps for this Pippin.
I inherited a WordPress site that was on WP 3.3.1 and upon upgrading it would not work properly. Traced it to jquery errors which were affecting things like widget drag/drop, etc. Chanced upon your site and realised that the theme must be loading its own version of jquery. Removed two lines that were loading an old, local version and left the wp_enqueue_script( โjqueryโ ); line and all fixed.
thanks again.
Perfect example of problems that arise with custom jQuery versions.