Stop using jQuery!! (all the time...)

This post is more than 2 years old.

I apologize for the link bait. I feel bad doing it. But - at least you know I'm not a slimy SEO person and there is something useful in this article. ;)

Yesterday I blogged a simple little POC (Proof of Concept) that demonstrated adding a class to a random list element. As I said in the post yesterday, this was rather trivial code, but I wanted to share it because of the use of LocalStorage.

About an hour or so after I posted it, something began to bug me. I opened up the template and looked at the Network requests in Chrome dev tools.

Just in case it isn't obvious, let me break it down for you. My HTML document was a bit over 1.5K. The jQuery library, compressed, was 33K. To be fair, my HTML was limited to what was required for the demo, but even if I increased the size of my document ten fold, it would still be less than the size of the jQuery library.

Don't get me wrong. I love jQuery. I love what it has done for my development, my career, and my skin care. (Um, ok.) That being said, you don't need jQuery as much as you think. Consider what my demo did:

  • Run a function when the DOM was loaded.
  • Find some DOM items via CSS selectors.
  • Remove a class from one thing, add it to another.

That's it. Surely I could do that without an entire library, right? First, I switched to listening for the DOMContentLoaded event.

For finding DOM items, I made use of querySelector and querySelectorAll.

For adding and removing classes, I made use of the classList property.

After these changes, the size of my application was pretty much next to nothing.

Here is the complete template. Any questions?

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ryan Anklam posted on 10/23/2012 at 6:10 PM

One thing I like to do if I just need a cross browser selector engine that works on IE6 & 7 use Sizzle.js instead of the entire jQuery code base. Same selector engine but without all of the other jQuery goodies.

Comment 2 by Tony Weeg posted on 10/23/2012 at 6:12 PM

this is great. it also smells like the start of a thinnerer jquery, jediQuery!

Comment 3 by Raymond Camden posted on 10/23/2012 at 6:19 PM

Ryan, you bring up a good point about compatibility. In my case, I made the conscious decision to not worry about IE6, because this functionality was used to highlight a LI. If it "breaks", then it isn't broken. You can see still the LI items. (In fact, since it loads with one highlighted, you still see a highlighted product.)

Christian Heilmann gave an incredible presentation last week (so good I'm going to blog the link a bit later) where he made an excellent point (I'll paraphrase here, any mistake is mine, not his)

"There is no such thing as a broken escalator. It's just stairs."

The context was in regards to how your code 'breaks' and what happens in those browsers.

In this - admittedly - trivial example, nothing is really lost.

Comment 4 by andy matthews posted on 10/23/2012 at 6:20 PM

Reminds me of this blog post I put out a few months ago:

http://andymatthews.net/rea...

Comment 5 by Phillip Senn posted on 10/23/2012 at 6:30 PM

I can't trust plain JavaScript. When IE uses one kind of event model and the rest of the world uses a different kind, I rely on jQuery to normalize that stuff.

What if you load the page a second time?
What if you load the page from another page on the site that had already loaded jQuery?

Comment 6 by Raymond Camden posted on 10/23/2012 at 6:36 PM

It depends on how far back in IE you want to handle. Look at my example. Does it need to work in IE6? I'd think not. Fewer and fewer people are supporting IE6. Even jQuery is dropping it next year. I'm not saying *no one* needs to support IE6, just saying it isn't necessarily something all of us have to support. And given that, doesn't it make sense to be _aware_ of what you can do in vanilla JS w/o a library?

Comment 7 by Phillip Senn posted on 10/23/2012 at 6:44 PM

Events may have been an example that was "not optimal".
Let's say you want to add two numbers together. Crockford in his video series on JavaScript, the Good Parts says to use:
A = +B +(+C);

You prefix both variables with a plus sign to make sure they are numbers, and wrap the second variable in parenthesis to guard against the two plus signs from touching each other and thus becoming B ++C.

Here again, a not optimal example, but you can see why I don't trust plain JavaScript. I would use a library to add two variables together and ensure that I don't get NaN as one of possible return values.

Especially if that library is cached.

Comment 8 by Raymond Camden posted on 10/23/2012 at 6:46 PM

Wow. Phillip... I respectfully disagree agree with you violently. ;)

Comment 9 by Adrian J. Moreno posted on 10/23/2012 at 7:00 PM

This looks like a Catch 22 situation.

Using jQuery makes the request heavier and "hides" what's really going on in the behavior (JavaScript) layer.

Not using jQuery will confuse the section of the interwebs that never took the time to actually learn JavaScript and you'll be deluged in "how do you do it with jQuery" requests.

:)

Comment 10 by Craig S posted on 10/23/2012 at 8:42 PM

One important thing to note regarding browser compatibility - querySelector and querySelectorAll only support whatever selectors the browser supports. So your example won't work in IE7 or IE8 either, since neither supports the :nth-child() selector. Sometimes it's best to just deal with the extra few kilobytes and use jQuery for things like this just to make sure you have your bases covered.

Comment 11 by Raymond Camden posted on 10/23/2012 at 9:00 PM

@Craig: Or - just use querySelectorAll and use the Nth item that way. One more additional line if I cared to support IE7/8. That's a lot better than loading the entire jQuery library.

To be clear, I'm not arguing for _never_ using jQuery. I'm just saying there are times when you don't need an entire library.

Comment 12 by Giancarlo Gomez posted on 10/23/2012 at 10:41 PM

Great Post Ray, I think what people need to understand is learn JavaScript, know your CSS and by now your HTML really should be up to par! We are web developers people!!! Also, why are people still supporting IE6? I think that argument is already dead in the water.

Comment 13 by Jack posted on 10/24/2012 at 1:03 AM

The escalator/stairs quip came from the immortal Mitch Hedberg: “An escalator can never break: it can only become stairs. You would never see an Escalator Temporarily Out Of Order sign, just Escalator Temporarily Stairs. Sorry for the convenience.” :)

Comment 14 by Raymond Camden posted on 10/24/2012 at 1:06 AM

Ah, nice, thanks Jack. Now I need to go ahead and quickly blog the presentation CH gave. I loved it.

Comment 15 by Roland posted on 10/24/2012 at 3:10 PM

Ray,

The library should be cached the second time (and thereafter) that you call the page, making the network traffic just a simple "not modified" response. Even better, if you're using a public CDN for the jquery libs, your browser probably already has it cached from other applications.

I don't disagree that we should avoid overusing libraries - especially for simple tasks - but you really shouldn't worry about the network impact if your web server is configured correctly or you're on a CDN.

Comment 16 by Adam Tuttle posted on 10/24/2012 at 3:23 PM

The thesis of your post is correct and fine, however, most people will already have the CDN hosted copy of jquery cached, so for most people it would be a non-issue.

Comment 17 by Raymond Camden posted on 10/24/2012 at 3:24 PM

@Roland: You are right, but, cached or not, if there is no need for an additional 30K of code, then why include it? Especially on mobile where the impact may be greater.

Comment 18 by Raymond Camden posted on 10/24/2012 at 3:25 PM

@Adam - your comment came in while I was replying to Roland, but, I'll just say ditto (my last comment ;)

I disagree that it is a non-issue on mobile. The parsing of the JS code _is_ an impact.

Comment 19 by Raymond Camden posted on 10/24/2012 at 3:26 PM

And again - much more than the impact of the library - it is the _need_ for the library. My main point here is to remind people that a lot of what you may use jQuery for can be accomplished in vanilla JS just as easily. We can agree on that, right?

Comment 20 by Scott Stroz posted on 10/24/2012 at 3:30 PM

Worried about a 30 kb file? Are we back in the 90's?

Comment 21 by Raymond Camden posted on 10/24/2012 at 3:32 PM

Seriously - if the only thing you take from this, "It's just 30K, why worry", then you are not getting the point.

Comment 22 by Roland posted on 10/24/2012 at 3:36 PM

Ray,

I would say "somewhat agree". For truly trivial code, yes I agree it's silly to use a library. But the second you get in to event handling and DOM manipulation (as in actually modifying it), I think a well-tested library is a better approach. I mean, sure you can write something that looks pretty simple, but does your event code work the same across all 4 major browsers, the minor ones, and all the mobile ones too? How do you know? Did you take the time to test it on every one of those platforms?

jQuery isn't just about providing easier syntax - it's also about providing consistent behavior models across many different platforms. It exists to worry about browser quirks so you don't have to (for the most part). Unless your code is super trivial, which it no longer is the second you're using events and searching the DOM, then I think the benefits of a library like jQuery far outweigh the minor penalty.

Comment 23 by Raymond Camden posted on 10/24/2012 at 3:39 PM

But Roland, I _did_ make use of events and I _did_ make use of DOM manipulation. It was a trivial example, but I did do that.

And whether you use jQuery, Ext, or no library, *yes*, you test across all platforms. Period. Using jQuery does not give you a free pass to skip testing. Agreed?

Comment 24 by Roland posted on 10/24/2012 at 3:48 PM

Agreed on the importance of testing. But also, it's just simply not economical to test on every browser and every platform and every version that may come up. Using jQ, you can be reasonably well assured it will work on the edge-case browsers/platforms/versions too.

I agree that in this particular case, especially given the intended usage and context, jQuery is unnecessary. However, if that code was very important to a production application that I was supporting, you can bet your behind I'd have used jQ.

Comment 25 by Raymond Camden posted on 10/24/2012 at 4:15 PM

I'm sorry - I don't buy the "can't afford to test" - that is just an excuse. If you want to support browsers X, Y, and Z, then you test for them. Period. (To be clear though - my assumption is that you make the decision to limit your support to X, Y, and Z, and not every browser.)

I'd argue "this particular case" is not the unusual. Obviously there is a wide range of AJAX apps out there. From something as simple as mine to as complex as GMail.

My hope here though is that folks are reminded of what vanilla JS can do. Things like querySelector and the classList API are very powerful and very well supported.

For example, querySelector has 93% support, including IE8. It is completely supported on mobile.

classList has less support - around 60%, with IE being the big one out. Mobile though is rock solid (outside of - oddly - Opera Mini).

Comment 26 by Raymond Camden posted on 10/24/2012 at 4:16 PM

Btw - I should point out I used caniuse.com for those stats. If you aren't using that site to check browser support - start. ;)

Comment 27 by Scott Stroz posted on 10/24/2012 at 4:23 PM

OK...I think I get the point of the post now. I don't think I agree, though.

jQuery has better compatibility than 60% for class manipulation. That right there is worth the extra 30kb, IMHO.

Comment 28 by Raymond Camden posted on 10/24/2012 at 4:42 PM

Let me ask this then. Did you know it was that easy?

dom.classList.add()

I worry about people who only use jQuery and don't even _look_ at what JS and the DOM APIs can do.

I know I didn't realize it was that easy.

Comment 29 by Scott Stroz posted on 10/24/2012 at 5:00 PM

I did not know it was that easy - and it really does not surprise me that the browser makers are adding stuff like this. But at 60% compatibility - with no IE - that is kind of a 'blocker' for most, I would assume.

Comment 30 by Manithan posted on 10/24/2012 at 5:01 PM

zeptojs is an alternative and liter version of jquery with same syntax for modern browsers

Comment 31 by Raymond Camden posted on 10/24/2012 at 5:04 PM

@Manithan: Zepto is nice. I used it recently to help with scroll/touch issues on mobile.

Comment 32 by Crawford Comeaux posted on 10/24/2012 at 8:25 PM

Just did a case-sensitive search through the jQuery & sizzle sources. Here's the result:

jQuery 1.8
----------
"IE"/"Internet Explorer" - 117
Safari - 11
Opera - 9
Webkit - 8
Firefox - 7
Chrome - 5
Gecko - 1

sizzle.js
---------
"IE"/"Internet Explorer" - 17
Opera - 5
Webkit - 2
Safari - 2
Chrome - 2
Firefox - 0
Gecko - 1

So I guess the quick & dirty response to "Why jQuery?" is "Microsoft."

It's possible to build your own version of jQuery that easily excludes components using Grunt - http://net.tutsplus.com/tut...

I wouldn't recommend doing that without modifying your development workflow to easily incorporate it and DOCUMENTING ALL PARTS OF IT. Don't make it so that anyone else working on the project in the future has to deal with figuring out why random bits of jQuery are throwing errors.

If you really want to get crazy, you could strip out the code for functions you don't need & replace them with some sort of lazy-loader. Bonus points go to whoever's lazy-loader also updates the custom core so that the lazy-loader's only called by the first visitor to the updated code.

Comment 33 by Crawford Comeaux posted on 10/24/2012 at 8:28 PM

I make no apologies for any showers that need to be taken after reading my previous post. You were asking for it, what with all that lurid talk of jQuery alternatives (or even going back to pure js!), so you were dirty to begin with!

Comment 34 by Raymond Camden posted on 10/24/2012 at 8:29 PM

All those mentions of IE - man - that must mean it is an AWESOME browser!

Comment 35 by Crawford Comeaux posted on 10/24/2012 at 9:43 PM

anSEOpersonsayswhat?

Comment 36 by Khoa posted on 10/25/2012 at 5:34 AM

I think it depends on where your interest lies. If JS is not your area of expertise and you need something quick but RELIABLE, I think it’s fine to jump right into using jQuery and learn how to use it and focus on your task at hand, not to worry about how things are done underneath. It's like using a computer, if you know how hardware/software works (maybe because you are an IT engineer, web developer, etc.), you can use your computer much more effectively. But it is not a requirement if all someone cares about is writing some documents and browsing the web.

Comment 37 by Douglas Hirsh posted on 10/27/2012 at 5:04 AM

I disagree with this post to a certain extent. Sure jQuery takes up 33k compressed, but if your production server is configured properly your JavaScript should be cached. No network connection should be made to get jQuery once it has been retrieved once. If you use a CDN to deliver jQuery to the client then you don't even need to worry about your server's configuration. Microsoft provides a free CDN for jQuery.

Comment 38 by Raymond Camden posted on 10/27/2012 at 7:35 PM

@Douglas: I feel like I'm repeating myself a bit here. ;) Again - this is a lot more than just size - it is more about remembering what can be done in JS w/o needing a library. I know I've said this a few times now in the comments, but I feel like folks aren't getting it.

Comment 39 by Edward Beckett posted on 11/7/2012 at 12:29 AM

If speed is an issue ... you might want to stay tuned to this awesome little project https://github.com/webjars/... ...

Comment 40 by Raymond Camden posted on 11/7/2012 at 12:34 AM

How would this be different than a gzipped jQuery?

Comment 41 by Edward Beckett posted on 11/7/2012 at 12:58 AM

None I presume ... I guess the real benefits would be aimed at packaging. I.E. backbone, twitter-bootstrap .. etc.

Comment 42 by Raymond Camden posted on 11/7/2012 at 1:05 AM

That I can see then. :)

Comment 43 by Edward Beckett posted on 11/7/2012 at 1:10 AM

I have to agree with you. Learning how to use jQuery effectively is just as important learning jQuery.

I recently re-developed a site that had five or six different versions of jQuery being called in-line throughout the site ... not fun to debug.

Comment 44 by Chris Ferdinandi posted on 2/13/2013 at 7:22 AM

I've just started moving away from jQuery myself, and have been using similar techniques to what you described in this post.

I'm not concerned with IE6 support, and querySelector's work great with IE8 and up, but IE7 is still a sticking point for me. Use is rapidly declining, but for those of us who support corporate clients, older IE support is sometimes still an unfortunate must.

Comment 45 by Raymond Camden posted on 4/26/2013 at 3:24 PM
Comment 46 by No one important posted on 10/21/2013 at 9:55 AM

I'll make a small rant here, just saying that although you still have a bit of a jQuery attachment; I very much abhor the nonsense. Others keep saying that jQuery makes their code "magically compatible" and fixes problems; but taking 3 seconds learning what jQuery is actually doing means you can ditch the 'weight' (and serious weight at that given how much the library does in the background) and directly manipulate the code. (Small scale cases, but that's what most people use jQuery for anyways)

Saying you need a library to tell if a variable is a number or not is plain ignorance about how javascript works. (Again, something I tend to find distasteful. Ideally, you should NEVER need "typeof" and writing code such that avoids type checking (without errors or *shudder* try catch) is faster and more 'compatible' than code that requires excessive type checking... I digress.)

But the worst offense I see with people using jQuery is that they're clearly idiots (sorry). I've seen several "professional" webpages that load the jQuery library only to use a single function that calls another function "document.getElementById()" at most using two or three functions for an ENTIRE MEMORY SUCKING LIBRARY! And you have to be the LOWEST common denominator to even BELIEVE jQuery magically makes "document.getElementById()" "compatible with IE6" (hint, it already is -__-;)

So for my perspective... it is just so much, why! Javascript is very powerful on its own, so much more so than anyone seems to realize... why do we have to wait for jQuery to make a bastardized interface instead of using what we already have?

[And of course, ranting about how great CSS selectors are when people are just using them because they don't know how anything about the DOM. (They are powerful, but if a short walk [ignoring idiots that keep yelling how slow *LONG* walking is (hint, jquery uses (or use to use) walks to emulate css selectors (err, I think... may have forgotten)] can get you where you want to be and you're "concerned" about "compatibility"... you don't just keep loading libraries hoping it all works. You make it compatible from step one.)]

[side note: even if jQuery would make your code "ie6" compatible... it would run so slowly and painfully that providing the SMART choice of "just let me have no javascript" which has many supports under html and css... but again, I digress; javascript for everything that doesn't need it... it is the future :(]

~No one has had no 'professional' work and probably is wrong on many levels but is opinionated and feels people should just learn how to program.

Comment 47 by Colm O&aposG posted on 10/6/2014 at 12:58 PM

DOMContentLoaded is not compatible with IE8 according https://developer.mozilla.o... so better to use readystatechange perhaps ?

https://developer.mozilla.o...

Best regards / Colm

Comment 48 by Raymond Camden posted on 10/6/2014 at 2:29 PM

If you need to support IE8, sure. I'd consider IE8 to be old enough to be not supported, but that's just me.

Comment 49 by Paul Browne posted on 2/24/2015 at 3:01 PM

I just converted my old javascript plugin https://github.com/Paul-Bro... to a pure javascript one https://github.com/Paul-Bro...