back
93 comments
"But you should always choose to use native DOM methods if they are available to you."

...when you're writing code that has to run at 60fps. The rest of the time, you categorically should always be using jQuery.

The native equivalent is very likely to be what jQuery is using under the bonnet, so jQuery is essentially just a wrapper most of the time. The performance hit from that wrapper is pretty close to zero. It's certainly nothing to worry about unless you're writing a game. The difference comes when jQuery isn't just a wrapper - likely for things where there are browser differences or performance improvements by doing things a different way. The majority of developers don't need to concern themselves with that sort of thing. We can just use jQuery and leave the performance 'hacks' to the jQuery team.

Additionally to that, mixing native and jQuery code makes things trickier to manage, especially if you manage a team of developers who don't all work the same way all the time. "Just use jQuery" is a good rule-of-thumb.

And lastly, jQuery has a vast pool of talent keeping up with browser tech better than you. Even the most avid follower of JS updates can't compete with a team of the standard jQuery draws upon. When a new method gets rolled in to the core of jQuery, something that speeds up selectors for example, your code improves without you doing any work. That'd a massive benefit.

(How much of a jQuery fanboy am I?!)

jQuery has a considerable performance cost for the abstractions it provides. It doesn't just call the native methods under the hood, it has to provide additional abstractions like chaining by wrapping every returned object into a jQuery object. In a lot of cases these abstractions aren't helpful because you need to understand exactly what jQuery is doing. If you compare the cost of native methods over what jQuery does you easily add 500 lines of javascript code on every method call.

Additionally, jQuery may not provide the abstractions you need or want. If you are using a high level framework that manages templating I would argue that you should use the abstractions designed by the framework and not the one-size-fits all ones that jQuery provides. There is a lot of functionality that jQuery provides that may not be relevant at all for you. jQuery animations are one example.

Using jQuery doesn't stop you from running into browser bugs. jQuery could help you out with basic things like selection and event handling but modern browsers are already much improved in this area.

I very much dislike the spaghetti code that over reliance on jQuery plugins results in. You have pieces of code that rely entirely on jQuery and can't be refactored out or reasoned with clearly. It is terribly unidiomatic in any case.

EDIT: That being said jQuery does have its place.

> jQuery has a considerable performance cost for the abstractions it provides ... add 500 lines of javascript code on every method call

But how much does this really matter, with modern high performance JS engines? The simple (and somewhat dismissive, I'll grant you) answer is of course it comes at performance cost, and it may be considerable. Comparatively. After implementing using jQuery, if some component is too slow, optimize. Rewrite using underlying core JS if you have to. Or better yet, reexamine what you are attempting and see if there's a better way.

> I very much dislike the spaghetti code that over reliance on jQuery plugins results in. You have pieces of code that rely entirely on jQuery and can't be refactored out or reasoned with clearly. It is terribly unidiomatic in any case.

Can you provide some examples of what you mean by this? Especially about it being unidiomatic (programming language idioms are a topic dear to my heart :)?

Personally, I find jQuery allows me to structure my javascript in a more coherent way, but that could have been greatly influenced by my relative experience with javascript before starting to use jQuery.

I'm with you in that argument, and here is some code to prove it; a little script that orders all 'divs' based on their size; the jQuery implementation freezes the page for a few seconds while the native one does not (Chrome 26 - i7/2.67GHz - W7 64 bits);

    $("div").sort(function(a, b){
        return $(a).width() * $(a).height() - ($(b).width() * $(b).height())
    });

    [].slice.call(document.getElementsByTagName('div')).sort(function(a, b){
        return a.clientWidth * a.clientHeight - (b.clientWidth * b.clientHeight)
    });
This. It's very fashionable to be "NoJQuery" these days, but I just don't have the time to worry that there may be a particular quirk for getting, say, the selected value of a dropdown list for a particular version of Safari during a full moon.
Not only games. Animations, dragging, building DOM - all are critcal situatons where every line counts, all benefit for close to metal code, every ms adds up.
> every ms adds up

Especially when any bloat is multiplied times however many visitors come to your site. Presenting an efficient front-end to your users is the polite thing to do, as it saves them both compute time and personal time. A lot of efficiency can be gained with tricks like removing dependencies, minimization through gzip, and ahead-of-time compiling.

> The performance hit from that wrapper is pretty close to zero

Unfortunately, that's rarely the case in my experience. But I'd be interested in any hard numbers you have here.

https://news.ycombinator.com/item?id=2261211 and responses has some hard data from about two years ago, but it's possible that jQuery has improved a lot in the meantime, of course.

So _if_ you're at a point where you care about the performance of your DOM code, jQuery can end up as a significant bottleneck. Most people are not at that point, most of the time. But most people _are_ at that point some of the time. The trick is recognizing when they are and what to do then.

I disagree, use JavaScript since that what you're supposed to be doing, using jQuery for everything is stupid
Would you also suggest people not use frameworks, since using the core language is what they are supposed to be doing?

Additionally, I guess an ORM or query builder of any sort isn't worth it either.

I suspect for a large percentage of sites JS on the client may be faster than the language the site was implemented in (even at a pure language level, ignoring that you offload computing very efficiently).

Why is using abstractions that we all (well, many, if not most) believe to be of benefit on the server any different when run on the client, especially when it's more efficient (compared to server) and scales better?

Sure, if someone thinks they have a need for raw javascript performance but they haven't tested and confirmed this, maybe blind assumption isn't the best way to proceed.

Author makes some points that are fine, I guess. A dev needs to carefully consider his audience and his fellow developers. If I can use jQuery and know that I'm not going to have cross-browser DOM API issues, then let me have it. Because the method simply doesn't work in older browsers (<IE8 http://caniuse.com/#search=queryselectorall) It's not entirely fair to say that `$(".my-class li:first-child")` is equal to `document.querySelectorAll(".my-class li:first-child")` or that `$('.my-class')` is equivalent to `document.getElementsByClassName('my-class')` (doesn't work in <IE9 http://caniuse.com/#search=getelementsbyclassname).

If you're building games or working with a team who does, I'm going to guess you're working with fairly edge functionality in browsers where javascript support is great. If you're building sites for clients who are still (sigh) using IE7 internally, you just can't get away with something quite so simple.

As another commenter mentioned: "Even the most avid follower of JS updates can't compete with a team of the standard jQuery draws upon. When a new method gets rolled in to the core of jQuery, something that speeds up selectors for example, your code improves without you doing any work."

This is the same reason I use a library for preprocessing my CSS. I'd rather update a gem and trust a team whose focus is processing CSS than try to rely on myself for keeping up to date with the pace of the CSS WG and browser vendors.

Also, for anyone wanting to dig around the jQuery source, James Padolsey made a great tool for it. I know I was pretty amazed to find out just how much is going on under the hood. http://james.padolsey.com/jquery/#v=git&fn=

Your arguments about compatibility with old browsers is great, but sadly the jQuery team doesn't actually believe that the problem they are solving should include compatibility with those versions of IE: the latest versions of jQuery decided that IE9 is the oldest version they are going to support going forward, as they didn't want to deal with the overhead (both in code and in development effort) of being a library designed to solve the problem of cross-browser JavaScript development... in a world where jQuery is just aiming for "improved syntax for DOM manipulation, compatible only with relatively recent browsers" (something I will argue has always been the case, due to their rather early deprecation of Safari 1.x), those examples cannot be dismissed: jQuery is just being used to avoid the complexity and verbosity of native APIs.
That's not true. There are two latest versions, one of which supports older browsers.
Question: if jQuery 2.0 only cares about modern browsers, can't they drastically improve performance by using these equivalent native functions behind the scenes?
What I'm curious about is, if these are equivalent, why doesn't JQuery just delegate to them in browsers where it is supported? Then you can get both the speed and the compatibility.
In the case of querySelectorAll, it does[1] (after performing some checks for easy wins) and if this test[2] is anything to go by, it can actually perform better in some cases.

[1] https://github.com/jquery/sizzle/blob/master/sizzle.js#L237

[2] http://jsperf.com/yui3-vs-jquery-selector-test-3/54

Personally I use jQuery Desconstructed when examining what's under the hood: http://www.keyframesandcode.com/resources/javascript/deconst...
Nicely done... right up until the end: "In that world if your game doesn’t run at 60 FPS, you might as well go work at Target."

Target made $69 billion dollars last year, and employs 365,000 people; I'd say there's no shame in working there.

If the cushy software dev life leaves you unemployed at some point, and you need a working-class job to pay bills while you hunt for something more to your liking, how will you spin your snarky attitude to your interviewer?

Nothing like insulting a third of a million people in one sentence (and really millions more that work jobs even worse than a typical Target job).
Saying that a job is crappy does not constitute insulting the people who have that job.
My job is to create web applications, not to keep track of every little idiosyncrasy in how various browsers have implemented core DOM methods. The jQuery team do a great job at keeping track of that stuff, and ensuring that things are consistent between different browsers. If I need something to be absolutely-blazingly-uncompromisingly fast I can use native methods, but for most people's use-cases, the performance hit you get with the abstraction is not sufficient enough to go back to using flint and steel to start a fire, after we invented the windproof lighter that is jQuery (or $FRAMEWORK).
Especially setting newer CSS attributes is much better with jQuery. You'll miss some vendor prefixes for some browsers if you do it on your own.

  $('#foo').css('transform', 'rotate(5deg)');
No need to look up all the needed prefixes.
For the people saying "just use jQuery always, is not that much of a perfomance hit", is just blatantly false; any complex manipulation and you start seeing the difference right away; many times I have to use both, native selectors for performance but mixed with jQuery (for efficiency).

Also, there are many scenarios where you can safely use things like querySelectorAll like browser extensions, WebGL apps, 2D canvas apps, (native) WebCam apps, WebRTC apps and many more. Furthermore, at this point is arguable how useful is to support IE8 and below.

And this article falls very short of what can be achieved with the native implementation. For example thanks to JS being prototypical you can borrow almost any method from Array to your NodeList.

    [].filter.call(document.getElementsByTagName('a'), function(e){
        return e.innerText === 'Brackets';
    });
> Furthermore, at this point is arguable how useful is to support IE8 and below

I'm seeing this a lot, but IE8 is the highest "blue e that goes on the internet" on Windows XP.

Its a brave (consumer-facing) business that can dump 10% of its customers [1]

[1] http://gs.statcounter.com/#browser_version-ww-monthly-201305...

If you ask them to use another browser some of them will; so I argue is less than 10%. As a side-note "document.querySelectorAll" is supported by IE8, but unfortunately it doesn't have Array.prototype.filter nor other basic array methods.
[].filter.call() creates unnecessary Array instance, you should be using Array.prototype.filter.call() instead. Still, such code breaks encapsulation and is plain ugly. It would make much more sense if document.getElementsByTagName() was returning Array instance or if NodeList was inheriting from Array.
Technically not because JS is prototypical, but because of how ES5 defines `Array.prototype.filter`.
I've seen a bunch of these noJQuery posts lately, but they've always focused on selectors. I'm curious what these people use for Ajax. Do they use the (very verbose) native syntax? Or are there any nice lighter weight libraries that separate out Ajax functionality into a readable abstraction like jQuery does?
So far, this has worked perfectly for me:

  function ajax(url, post_parameters, callback, data)
  {
  	var http = new XMLHttpRequest();
  	if (http != undefined)
  	{
  		http.open(post_parameters == '' ? 'GET' : 'POST', url, true);
  		http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  		http.onreadystatechange = function()
  		{
  			if (callback != null)
  			{
  				callback(this.readyState, this.status, this.responseText, data);
  				// readyStates: UNSENT = 0, OPENED = 1, HEADERS_RECEIVED = 2, LOADING = 3, DONE = 4;
  			}
  		};
  		http.send(post_parameters);
  		return true;
  	}
  	else
  	{
  		console.log("no ajax..  sorry.");
  		return false;
  	}
  }
Definitely a standard issue popularity backlash. See: PHP. Once something achieves overwhelming scale in tech, the majority turns on it because: dominance != cool.
Native APIs are the future, and everyone should learn to use them, but there are still too many gotchas and verbosity. Take a look at the code in rye.js[1], these are the most minimalistic wrappers to native APIs you'll ever get before ES6: https://github.com/ryejs/rye/blob/master/lib/manipulation.js

This is what I expected jQuery 2.0 would attempt, and the shape most browser libraries will take in the not-so-distant future.

Interesting 'innerHTML' is mentioned as a crappy native equivalent. In theory, I agree. But last time I compared innerHTML vs DOM fragments, innerHTML was much much faster across the browsers I tried (this was just before JITs for JS became common place). The tradeoff it seems is the browsers native HTML parser and serialization vs holding a DOM tree in JS, and for large sets at least, innerHTML won handily.
That has been my experience as well, in fact, I believe the native DocumentFragment code should be slower than the jQuery innerHTML-based code.
By using innerHTML you lose event bindings of all elements in the container you're appending data to, and the state of inputs.
innerHTML isn't W3C compliant. Why are you using it in the first place?
querySelectorAll is great, assuming you know your users aren't using IE 6 / 7. Cross browser support is really where jQuery shines.

jQuery is starting to become less relevant as newer browsers start to include the same functionality natively, and I say that as a massive fan of jQuery.

Why not use a polyfill to get the same functionality on older browsers? That also gives you the benefits of better performance on browsers that do support the native version.
jQuery is a pleasure to use. It's just plain useful. If you need to manipulate the DOM in legacy IE, nothing compares. I'm reading a lot of complaints about the overhead for legacy IE support (presumably from people with better clients than mine...) but I'm surprised no one has mentioned Zepto. I haven't had a chance to use it yet, but isn't it just a stand in for jQuery where legacy support gets stripped out? I'd love to see the benchmarks.
No, that's jQuery 2.0. Also, Zepto is slower.
I'm curious - is there actually much overhead if your browser supports these native methods? Surely jQuery just goes straight to them?

For anyone who knows jQuery internals, does it check for browser compatibility on every call, or does it check once, and then hardwire up the correct methods for the next call?

Right from the source: "Sets document-related variables once based on the current document" [1]. It's a very readable document and the comments give good overview about quirks you have to be aware of.

My personal opinion: not using jQuery (or similar library) for normal webpages is premature optimization and it will hurt more than help.

[1] https://github.com/jquery/sizzle/blob/master/dist/sizzle.js#...

jQuery has lots of feature checks, a long dependency tree, and a half-decade of accumulated bug reports and corner-cases. It also implements custom selectors and "fixes" behaviors in querySelectorAll that often leads to a significant drop in performance. Not that you'll notice unless you're using the DOM for rendering complex graphics/UI :)
A lot of the checks are done on initialisation. Take a look at jQuery.support - http://api.jquery.com/jQuery.support/ - it's around line 1300 in http://code.jquery.com/jquery-1.9.1.js
jQuery is much much slower for many selectors, often orders of magnitude slower.
Great article. Newer developers are spoiled by jQuery and don't realize that all it does is make native javascript a bit cleaner. However, one nightmare javascript task that this article overlooks is ajax. Native javascript ajax is no where near as simple without jquery
Cool article. I'm a big fan of noQuery. One thing you could improve is regarding appending, using insertAdjacentHTML instead of constructing the DOM manually in a document fragment. It's significantly less code and should perform better.
Nice point.. i wasn't a ware that using the native selectors should give major performance impact. I will try to measure it and will see, Thanks