December 31, 2020

jQuery vs. Vanilla JS - or A rant against jQuery

jQuery was a great library upon its release, but since 2006, web APIs have improved. Is jQuery really needed anymore? Is all that weight worth it?

jQuery is a JavaScript library that was first released in 2006. The library made a lot of things easier, like DOM manipulation, form validation, cross-browser compatibility and more. Since that first release, there have been 2 major updates (with lots of minor updates), and its currently at v3.5.0 (as of Dec 28, 2020). I have found that, as robust as jQuery is, it may not be needed. It has a lot of problems, not limited to file size, questionable functionality, and performance issues. It'd be disingenuous to say that its completely useless, because I certainly would not be here arguing against using it if it weren't for jQuery itself. I started building on the web in 2012. After building a few basic sites, I quickly learned that I needed to make them work across platforms. Building responsive sites is made much easier with JavaScript, but I had no skills there. To me, JavaScript was a "real" programming language, and since I was new to all this, I had no clue where to start. After finding jQuery in a StackOverflow thread, I loaded jQuery from an external source and copy/pasted the demo code. And it worked! I was sold! jQuery was the answer! But now, it's probably not

jQuery is kinda big

Even the minified version of the latest release is 87.4kb. Obviously, that'll affect performance, especially if your site is calling from a CDN, which probably shouldn't be done. Even if you've downloaded jQuery, it still bloats your site's size by 87.4kb. And, you probably don't need to use all of jQuery, so much of that is extraneous. "But what about custom builds?" Ok, so you can make custom versions of jQuery that use only the modules you actually need. And that's a great solution! You can even download those builds and serve them locally! But I'll still contend that jQuery is still not needed, for reasons I'll get in to.

Maintenance and Versioning

Using the latest version of jQuery is important because new versions often have security and bug fixes. But manually updating that means a lot of file updating if you're serving locally, and tag updating if you're using a CDN. You could use the automatically updating CDN solution, which makes it less manual, but then you have to scramble to rebuild broken code when that version drops without warning. Anyways, as previously mentioned, you probably shouldn't use a CDN.


So, let's imagine that the file size issue has been handled and every user has an up-to-date version of jQuery cached. A perfect scenario: no extra load time, no extra bandwidth needed. Cool, your site is served up super fast. But on large projects, jQuery can slow things down. Especially if a lot of DOM manipulation is going on. Let's run a test to see which is faster between vanilla JS and jQuery. We'll attach 10,000 elements to the DOM and time it. I'll log the time before and after the function runs and compare the two times.

See the Pen 10k elements by Nate Northway (@the_Northway) on CodePen.

So, using this method, JavaScript attaches 10,000 elements to the DOM in 36ms, on average. Moving on to using jQuery:

See the Pen 10k elements with jQuery by Nate Northway (@the_Northway) on CodePen.

Using jQuery the result is 375.4ms on average, meaning that it takes 10x longer to do this basic thing in jQuery. I'm not gonna go into details on the why here, but I took inspiration to run this test from Moon on Medium, which does.

Vanilla JS vs. jQuery

There is so much that jQuery does that can now be done natively with vanilla JavaScript. jQuery had its place in 2006, when DOM APIs, element manipulation, and so much more was difficult (if not impossible) to do with vanilla JS. But web APIs have expanded significantly, and a lot more stuff is possible (and sometimes even easier) with vanilla JS. So, why load a large file when it might not be necessary?

Benefits of Vanilla

I'm not gonna spend this whole article dogging on jQuery, I'm also gonna talk about why vanilla JS is good. For starters, it's already there! Yep, you don't have to load anything, you may not even have to call a different script, depending how lean your code is/what you're doing. If all you need JS for is to toggle a class on a button click, there's nothing wrong (in my opinion) with just dropping that right in the HTML with the <script> tag.

It stays up to date

That's right, browsers automatically update to the latest versions so you don't have to! There are some compatibility things that sometimes get in the way, but you don't have to worry about maintaining versions on a production site, a test site, and a local environment. You also don't have to worry about calling an external script to use the code that you wrote and serve locally.

You (probably) don't need jQuery

There is so much that jQuery was designed to do that can be done natively now that APIs have been further developed. I'm just gonna run through a quick-hit list of things that vanilla JavaScript does just as well (and sometimes better than) as jQuery.
$() selector The jQuery selector allows you to find an element by a CSS selector. Vanilla JS has many equivalents, the most similar of which is querySelectorAll(), which accepts a CSS selector as an argument. That function will return either an element or a nodeList, which as a lot of cool things attached to it. Additionally, there's the following functions:
  • getElementById("element"): returns a single element
  • querySelector("p"): a single element is returned, which matches the passed CSS selector
  • getElementsByName("inputName"): a nodeList of elements is returned with the given name attribute
  • getElementsByTagName("p"): this returns a nodeList of elements that match the given tag name
And there's a lot more. The cool thing about the functions that return a nodeList are all the functions that come with that. Iterating over a list is easy with .forEach, which eliminates the need for counting and looping, which isn't difficult, but still, making anything easier is good. The other cool thing about these selectors is that they can be run in different contexts, so if you run it on the document, the reach is document-wide, but if you run it on a previously selected element, the function returns results just within that element, which is (in my opinion, at least) easier to read than jQuery's element.find(). css() The css() function in jQuery is a getter/setter for the CSS properties of the relevant element. Personally, I think setting CSS in Vanilla JS is better because it's a bit more semantic, and easier to read, especially for beginners. Reading is a little more complex, but also programatically a little easier to understand. To get CSS in Vanilla JS, its as easy as window.getComputedStyle(element). The object returned is read-only. To manipulate CSS in Vanilla JS, I suggest using class names and toggling them based on events, and using those class names in your CSS. But if you really wanna use inline styles, you could use the property. To change font color, for example, you could use = blue;. I strongly urge you to not do this and to toggle classes instead. There are known security risks to using inline styles. Class Functions Vanilla JS has some great and easy-to-use class functionality. In jQuery, it is arguably very simple to read, change, edit, and toggle class names with functions like addClass(), hasClass(), removeClass(), and toggleClass(). In Vanilla JS, I like it a lot more, though.
  • element.classList.add("something");: adds a class to an element's classList
  • element.classList.remove("something");: removes a class from an element's classList
  • element.classList.contains("something");: checks if an element's classList includes "something"
  • element.classList.toggle("something");: toggles an element's class
Making things easier There are a few things that using vanilla JS makes easier, like finding an element's position. In jQuery:

var offset = el.offset();
  top: 123,
  left: 123
In vanilla JS, the return is a lot more verbose and useful.

var offset = el.getBoundingClientRect();
  x : 0,
  y : 50,
  width : 440,
  height : 240,
  top : 50,
  right : 440,
  bottom : 290,
  left : 0
I could keep going on about DOM Manipulation, AJAX, HTML element property manipulation, array indexing, and so much more. But this article is long enough and other people talk about these things better than I could. Below is a list of sources I used to fuel this thought train.