jQuery-itis

As a webdeveloper, I have of course used jQuery. A lot. And of course, when I first learned about jQuery years ago, I was taken by it, completely. I loved how I didn’t have to write a function with that huge try-catch block, just to do a simple AJAX call, for example. For those of you who weren’t around back in the days where IE6 was still supported, or for those of you who suffer from accute jQuery-itis, here’s a snippet of code to show how we used to perform a simple AJAX request:

var xhr;
try{
    xhr = new XMLHttpRequest();
} catch(error) {
    try{
        xhr = new ActiveXObject('Msxml2.XMLHTTP');
    } catch(error) {
        try{
            xhr = newActiveXObject('Microsoft.XMLHTTP');
        } catch(error) {
            throw new Error('no Ajax support?');
        }
    }
}
xhr.onreadystatechange = function()
{
    if (this.readyState === 4 && this.readyState === 200)
    {
        console.log(this.responseText);
    }
};
xhr.open('GET', 'your/url?id=123');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send();

If you see this, you probably understand why jQuery took off the way it did. Compare this code to:

$.ajax({
    url : 'your/url',
    data: {id: 123},
    type:'GET',
    success:function(res)
    {
        console.log(res);
    }
});

But this is just an example of a simple request. When you consider multi-dimensional objects, to be sent as a POST request, the temptation to use the easy jQuery code is just too great to resist, for any developer. It’s a well-known fact that good programmers are lazy: they are reluctant to write code that already has been written for them.
So I, like most of my colleges, just made a habit of including jQuery in all our projects. Most of us still do, as a matter of fact.

We’ve all got a bad case of jQuery-itis: we’ve gotten so used to jQuery over the years, that we’ve forgotten to ask ourself this one, very fundamental and important question:

Do we still actually need jQuery?

I mean: of course, back in the days when Microsoft constantly bullied the world into supporting that outdated hunk of [] that we call IE6, and that for every new feature or event, they implemented their own “better” version of the same thing, then yes: a tool that dealt with X-browser issues was indeed a very good thing to have.
But since IE6, Microsoft has grown up quite a bit: it’s no longer as dominant as once it had been, and started to get rid of its ActiveX objects. It conformed to the standard more and more, instead of going against it. The JavaScript engines in modern day browsers are all pretty similar in terms of code support. Writing VanillaJS now no longer means that your code will cause problems for half of the clients. So why do we still use jQuery, if X-browser issues are no longer that much of a problem?

The pro’s

A short list of pro’s I can come up with:

  • normalized code. jQuery’s syntax imposes a certain standard. Neigh on everyone writes the code in a similar way
  • often less code to maintain, and less time spent developing. Time is money…
  • Less JS-minded people can work on your code. A blessing in disguise, though: Do we really want less capable people messing up our code?
  • Friendly, welcoming documentation, all quite to the point and concise.
  • Most importantly: A vast amount of plugins, readily available

The normalization of code is very important when you work with other people on the same project. Nobody can deny that. jQuery seems to have this effect on developers, to all write code in the same style. I’ve never seen code like this, for example:

$('#foo').on(
    'click',
    'li',
    function(e)
    {
        console.log(
            $(this)
        );
    }
);

Things like this may seem banal to some of you, but trust me: when you’re dealing with a sizeable front-end code base, it matters. If everyone just coded using their style, you’ll soon find yourself in a padded cell, whispering to yourself: “The horror… the horror”..

The snippet I wrote above is one of the cases where VanillaJS isn’t harder to write, per se, but you do end up with less code to maintain, which again is something that is appealing to developers. However, consider what this code does: it delegates click events on li elements that are children of #foo. Great, now let’s see how much code we’re actually saving over VanillaJS:

document.querySelector('#foo').addEventListener('click', function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if(e.tagName.toLowerCase()==='li')
    {//jQ does this check internally
        console.log(this);
    }
},false);

The line where I check for the e parameter is optional, because this deals with IE<9 compatibility issues. For the most part, the code isn’t actually that much shorter. In fact, some things are actually shorter in VannilaJS then their jQuery counterparts: this.id vs $(this).attr('id'); for example.
But the main problem you’ll face when you suggest to use this kind of code over the jQuery version is that it doesn’t look very junior-friendly. To understand the code, you’ll have to check MDN, which is great, but not as friendly a source as api.jquery.com is.

To me then, the last two pro’s really are irrelevant: if you shy away from VanillaJS because you find MDN’s (excellent) documentation too technical and not welcoming enough, then you are the one who has a problem. If you find the VanillaJS code not welcoming, or hard to understand, then perhaps consider spending some time to actually learn the language you are trying to write in. JavaScript isn’t a big language, nor is it particularly hard. It just has a few quirks and oddities, but once you understand, for example, how the this keyword works, and how closures can be used, then you’ll soon find out how expressive JS can be, if used correctly.

The Con’s

Again, a short list of cons, and I’ll elaborate on them later on:

  • jQuery is used too much, it’s overkill in many situations
  • jQuery is so wide-spread that too many knuckle dragging, drooling Nickleback-fans are using it. Thinking it’s the digital equivalent of the second coming, they bully people into using jQuery as a solution to every single problem, and write woefully inaccurate (or plain wrong) blogs about it.
  • jQuery is a suite off the peg. We all buy suits off the peg, well most of us anyway. Does that mean there isn’t a marked for suits made to measure? Of course not. The people contributing to jQuery aren’t tailoring to your specific needs.
  • jQuery isn’t what you call modular or light-weight, and it doesn’t speed up your code. If you only use 1 feature, why include the entire thing? if you are worried about blocking the UI, then look into more efficient coding techniques, and get rid of any toolkit.

By jQuery being overkill I simply see it as using an automatic riffle to swat a fly. That’s just plain silly. Just like a Java “Hello, world” program just looks ludicrously over-engineered, so does a bit of JavaScript that merely changes the background colour of a page on load, if it uses jQuery to do so.

Anything that is as wide-spread as jQuery has bad information on the web. In order not to seem biassed, and because the location where such bad info can be found is subject to change, I’m not going to link to any of those blogs or “tutorial spots”, but I assume most of you have seen code that is just ludicrously inaccurate, inefficient and generally bad, being posted as an example of how to do X.

By jQuery not being tailor-made, I’m actually hinting at the simple fact that jQuery started off as a great tool to circumvent the limitations imposed on you by both X-browser quirks, and the DOM API (which isn’t part of JavaScript, in fact).
If you are struggling with a particular problem, that has more to do with the limitations of JavaScript’s runtime itself, then jQuery can’t help you. At all. It is a JavaScript toolkit itself, so it is bound by the same limitiations as you are.
I have a couple of examples where people are seemingly expecting jQuery to “see their logic” or to sort of know what they are trying to do. But, sorry, programming doesn’t work that way.

The last thing, about jQuery not being modular, is something that they’ve tried to address with jQuery 2 but, perhaps indicative of the community that uses jQuery, this hasn’t really caught on. Another reason why might be that jQuery 2 broke compatibility with IE6/7/8, too. The argument pro jQuery of being compatible with older browsers was dropped, and the release note even mentions this decision can even affect IE9.
Either way, most people still use a version of jQuery 1.x, blinldy including every bell and whistle this ships with, and probably never even using half of them. That, to me, is just a bit silly. There are things I find even sillier, still, but I’ve decided to devote a third category to those aspects of jQuery-itis sufferers

Sickening

Yes, by now you all realize that I’m not too keen on jQuery, and I would like to see people use it a lot less. So far, though, I’ve mainly focussed on things that people put forward as reasons to use jQuery, and why I find them either irrelevant or invalid.
There are other things that are just plain insane. These crimes against common sense will now be put on trial.

$.create

Are you kidding me? A lot of people tell me this helps them work with prototype-chains, and write good OO JavaScript code. They are either blind, moronic or criminally insane. Before we continue, consider the actual expression $.create. What does it mean, to a JS engine it means: Use variable $ (which, incidentally is a global!), it should be an object, and use the property create, which is a function object.

You use this joke to write OO JavaScript, but you start off by including a monolithic toolkit, which is assigned in the global namespace, and rely in such a non-oo dependency to write good OO code? Am I the only person to see the lunacy in that? Really?
If you don’t see the lunacy, then compare what $.create does to what ECMAScript 5’s Object.create can do. Still think this jQuery gimic is worth including the entire toolkit?

O tempora, O mores

Now I’m going to sound like an old fart, but then, this is my blog, and I’m free to complain as much as I like. You don’t have to read this after all.
A lot of newbies/amateurs who pick up jQuery think it’s a different language all together. It isn’t. It’s JavaScript, pure and simple. Hence: everything jQuery does, can be done in JavaScript. Some newbies, however, seem to think that jQuery is the better way of doing things, and ask questions like: “I have this JS code, how would I write this in jQuery”, to which I of course answer: “You don’t. VanillaJS is faster, and if it works, it works. No need to wrap it all up in jQ”.
This is generally followed by a frown, a stare of disbelief, and the onset of panic in the eyes of the intern. They can’t seem to believe I just told them not to bother using jQuery.

This reaction however is nothing compared to the bemused looks I got when I tried to explain to an intern that he could just pass a function name as a callback to any of the jQuery methods. I noticed he didn’t understand what I meant, so I said that JavaScript is, essentially, a functional language, and so functions were first-class objects.
Still no aha-Erlebnis. I explained that function names are, essentially like variables, and that they could be passed to functions as arguments, and likewise: could be returned. Still no reaction.
It was then that I realized that people who manage to build great interfaces with jQuery don’t understand what they are writing. They don’t have a clue what happens to their callback function, and when it is actually invoked. They don’t have even the faintest idea where the this reference is bound: They don’t understand JavaScript at all.

That is, to me, more than just disturbing, or worrying: this is sickening. People are creating plugins, scripts that they themselves don’t really understand. Suppose one of them puts a plugin on github, how is that person expected to ever understand a pull request that actually improves the code, if he can’t work out why the contributor wraps half of the functions in another function? Closures are so powerful, yet most jQ code out there doesn’t seem to use them. How common is it to see code like this:

$('#button').on('click',function()
{
    $('#target').html('Button was clicked');
});

Pretty common, of course. I’ve asked countless jQuery fanatics: count the number of function calls in this code, just over half of them get it right. Oh, if you were counting: the answer is 4.

Now look into the jQuery source code, and try to count the number of function calls that take place behind the scenes… Nobody really knows that. Last time I checked, I believe it was another 5 calls, just for the first line of code. Then, before the callback is invoked (handling an actuall click event) another 5 calls are required: jQuery’s own handler, which checks if jQuery has listeners bound, then the callback’s  context is bound (which is not being used here!), the callback is invoked, its return value is evaluated (remember: event callback + return false in jQuery…), and depending on the return value a couple of more functions can be called.
The function body itself calls even more jQuery functions: a DOM query performs 3 internat jQuery functions, and the html method can, depending on the html string and browser result in God knows how many additional calls. It’s insane. Really, it is.

A first step in saving the number of function calls, while sticking to jQuery would be the use of closures, which a lot of people don’t understand:

$('#button').on('click',(function()
{
    var target = $('#target');
    return function()
    {
        target.html('Button was clicked');
    };
}()));

What’s the difference now? well: we only query the DOM once for the target element, regardless of how many times this callback is being invoked. However, as I explained: there are still a lot of internal jQuery calls being performed, which are so easily avoided by just not using jQ. As I explained before: the code really isn’t any harder to write/understand. The main difference between the VanillaJS and jQ code is efficiency, jQ can’t even come close to VanillaJS. Count the function calls in this code:

document.querySelector('#button').addEventListener('click', (function()
{
    var target = document.querySelector('#target');
    return function()
    {
        target.innerHTML = 'Button clicked';
    };
}()), false);

Ok, so it’s the same as the most efficient jQ version of the same code: 4. the document.querySelector method is invoked twice, and the IIFE (Immediatly Invoked Function Expression) returns the handler to addEventListener. That totals 4 calls. These calls are also performed by jQuery however, only jQuery wraps them in custom functions, which need to be invoked first. But the real difference becomes apparent when we compare the number of calls that are made when the button is actually clicked: this code simply invokes 1 function: the one that sets the innerHTML property. Nothing else.

The moment you understand how this code works, and you realize just how easy this is, will be the day you say farewell to jQuery.

Why the hate?

I don’t hate jQuery. I hate the way it is used, and how people look at it. Well, “hate” probably isn’t the right word, resent or disapprove would be more accurate. Either way, to me jQuery, and other toolkits like prototype.js have had their use. In some cases, they still are very useful. It’s clear that these tools have inspired the ECMAScript committee. They people on that committee have looked at the toolkits, to see what our needs are, how the language is being used. As a result, ECMAScript 5 has implemented things like Array.prototype.forEach.

Choosing a toolkit, then, is like voting: You choose the toolkit that best represents your needs, and hope others do, too. The guys over at ECMA notice toolkit X is gaining support, because it fills a specific need, and they might consider implementing that feature as a result.
But because jQuery has become the darling of the web, jQ mobile is the default go-to toolkit for many, ignoring possible gems that other people might have created. Or worse, still: People with good ideas might decide not to put their idea into practice, because everyone uses jQ anyways. We could be missing out, big time…
As it stands, jQ mobile is the biggest toolkit out there, so it stands to reason that its development has the biggest impact on the ECMAScript standards of the (near) future.

The mobile browser world is in dire need for some standardization, and until the dust settles over mobile browser-land, we will have to use toolkits. But we should choose our toolkits carefully, not blindly. It is our responsability to be on the lookout for great ideas in toolkits, so the next ECMA standard can adopt that same idea. We can all benefit from it.

Advertisements
This entry was posted in webdevelopment and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s