Are you sure you need jQuery?
Tags: javascript, performance, a11y
Published: 2019-08-27 20:09:20

You use jQuery.

Everyone does.

It is an awesome library, it took us out of the collective pit of despair that was js support in the early 2000's. It was an essential founding stone on the modern web.

But we are not there anymore. Javascript support is much more complete and uniform across most browsers. ES6 is almost commonplace now. Browsers update regularly and automatically.

Sure thing jQuery does download compile and run awesomely on your cutting edge 16 cores, 32GB RAM laptop connected to metropolitan fiber-bandwidth wi-fi. But that might not be the case for many of your users. Slow loading pages are an issue for them, but also for you, because [most mobile users leave any page taking more than 3s to load](https://www.marketingdive.com/news/google-53-of-mobile-users-abandon-sites-that-take-over-3-seconds-to-load/426070/).

The thing is, do you _really_ need it?

Because most of the times, what we do with jQuery is:

* select dom nodes based on css
* add or remove classes to html elements
* add or remove attributes to html elements
* add or remove content to html elements
* fetch some new html over an ajax call

And you know what? You don't need jQuery for that.

So I am going to give you two alternatives:

- [You only use a little jquery](#you-only-use-a-little-jquery)
- [You use most of jquery](#you-use-most-of-jquery)

and

- [A final word of caution](#a-final-word-of-caution)


## You only use a little jquery

You are doing a brochure-style site, or adding small interaction enhancements to a not-so-dynamic web. It is not an _app_, those are using frameworks and we know it. It is your portfolio, your bosses' niece kite-flying home page, or a simple landing+sign-up for a really cool but still-unreleased bigger project. Then let me show you:

### DOM manipulation

| When you were doing...             | Do this instead                            |
|---                                 |---                                         |
| `$('.someclass')`                  | `document.querySelectorAll('.someclass')`  |
| `$('.someclass')[0]`               | `document.querySelector('.someclass')`     |
| `$element.remove()`                | `element.remove()`  |
| `$element.prepend(otherElement)`   | `element.prepend(otherElement)` |
| `$element.before(otherElement)`    | `element.before(otherElement)` |
| `element.addClass('some')`         | `element.classList.add('some')` |
| `$element.removeClass('some')`     | `element.classList.remove('some')` |
| `$element.toggleClass('some')`     | `element.classList.toggle('some')` |
| `const parent = $element.parent()` | `const parent = element.parentNode` |
| `const clone = $element.clone()`   | `const clone = element.cloneNode(true)` |


### Array manipulation

| When you were doing...      | Do this instead                     |
|---                          |---                                  |
| `$.isArray(a)`              | `Array.isArray(a)`                  |
| `$.inArray(item, arr)`      | `arr.indexOf(item) > -1`            |
| `$.each(arr, (i, v) => {})` | `arr.forEach((value, index) => {})` |
| `$.map(arr, (v, i) => {})`  | `arr.map((value, index) => {})`     |
| `$.grep(arr, (v, i) => {})` | `arr.filter((value, index) => {})`  |

If you are missing a **lot** of stuff from here but still would like to skip jQuery, have a look at [LoDash](https://lodash.com/docs) (~4kB gzipped)

### Events 

| When you were doing...      | Do this instead            |
|---                          |---                         |
| `$el.on('click', e => { })` | `el.addEventListener('click', e => { })` |

Bear in mind that jquery allows you to observe on an element _collection_, but if you used `querySelectorAll` then you need to observe every element of the result, like this:

```js
// https://stackoverflow.com/a/50101839/97635
document.
  querySelectorAll('.tracked').
  forEach(input => input.addEventListener('click', this.trackLink));
```

### Ajax calls

XMLHttpRequest is a handful, and I am not going yo convince you to ditch your handy `$.ajax({})` call for it, so let's talk about [Fetch](https://fetch.spec.whatwg.org). Fetch is a modern replacement for XMLHttpRequest, but it [does not have same widespread support](https://caniuse.com/#search=fetch) as the rest of the API's we have been mentioning, so it is worth mentioning that there is [a polifyll available](https://github.com/github/fetch), that you could serve only to the relevant browsers, keeping everyone else on a byte diet.

```js
fetch('/users.html')
  .then(function(response) {
    return response.text()
  }).then(function(body) {
    document.querySelector('#userlist').innerHTML = body
  })
```

## You use **most** of jquery

Be this because you have an existing and big base of code, or you feel _too comfortable_ to try and do things differently...

Then I want to introduce you to [Zepto.js](https://zeptojs.com/)
Zepto is (in their onw words) a minimalist JavaScript library for modern browsers with a largely jQuery-compatible API. If you use jQuery, you already know how to use Zepto.

It is 9.6k when gzipped, so already smaller than your logo. Go check it.

## A final word of caution

If you are using jquery, loving it, and serving it from a blazing fast CDN, minified and gzipped (28.87 KB), then maybe it beats going out of your way to avoid it.

Don't bother with any of the above if you are serving a multi-megabyte framework-dependent frontend MVC SPA. Focus on your framework best practices, and learn its quirks.

JQuery is awesome, I have no ill intend towards it. It has become the _de facto_ plumbing of the web because it does it job. The only problem with being **so** succesful that it is _ubiquitous_ is that we no longer **question** it. And you should question everything.

As always, I am happy to read your takes on this matter, do you _count bytes_?, do you look at your google analytics to profile your users and their devices?