DEV Community

loading...

Discussion on: JQuery Footguns?

Collapse
ahferroin7 profile image
Austin S. Hemmelgarn

Short list of things that come to mind:

  • Take the time to compare the jQuery AJAX stuff to a minimal open-coded implementation covering exactly what you need. You'll often find that just coding it yourself will both save space (if you can use a custom build of jQuery with the AJAX stuff stripped out) and save time. It also makes migrating to jQuery alternatives a bit easier. The same goes for the animation stuff (by the way, if you need animations more powerful than the basic canned stuff jQuery provides, I'd suggest looking into Anime.js, it's fast, tiny, and very powerful).
  • Cache your jQuery objects. For really trivial cases, performance isn't too bad, but the moment you start getting complex selectors (or using class selectors on older browsers), you will see some serious performance issues.
  • Use .prop() instead of .attr() whenever you can. It's significantly more efficient, and it ensures that the browser's internal understanding of the DOM state gets updated properly. Even further, use specific jQuery methods for the properties that have them (value for example, which has the .val() method).
  • Use event delegation whenever possible. This will help keep the number of event listeners down, which in turn helps a lot with app performance on many devices. Using event delegation also means you don't have to care if the specific element you want to match on even exists in the DOM when you add the event.
  • Make sure to keep track of which variables refer to jQuery objects. Most people just prefix such variables with $ as a reminder. This is more a case of writing readable code than actual performance.
  • Remember that jQuery always returns a valid object, even if your selector matches nothing (in that case, you get an empty jQuery object). This actually does have practical uses, but it also means that things that would crash if done through VanillaJS methods will silently fail to do what they say when using jQuery.
  • Keep in mind that many jQuery methods apply to all matched elements. In a lot of cases, there's no point in manually looping over the returned results of a jQuery selector call because you can simply update everything with one function call (which will be faster, especially for very large numbers of matched nodes).
  • Pretty much every jQuery method which mutates the state of the DOM returns the jQuery object it was called on. As such, you can often chain a series of methods that modify your selected element. While this doesn't make things any faster (at least, not measurably on any sane JS engine), it does make the JS code a bit smaller (each method you chain this way saves 2 bytes of code after running the source through a minifier).
  • Certain jQuery methods (most notably .addClass() and .removeClass()) are functionally idempotent and declarative. Put simply, $('#foo').removeClass('bar') will never return an error, and will always ensure that the element with ID foo does not have the class bar. As a result, stuff like this just wastes time:
if (!$('#foo').hasClass('bar')) {
    $('#foo').removeClass('bar')
}

Also, you might want to see if you can convince the decision maker to use Cash instead, it's like jQuery, just significantly smaller and significantly faster (and it unfortunately doesn't work with Bootstrap or some popular jQuery plugins like select2).

Collapse
deciduously profile image
Ben Lovy Author • Edited

Wow, this is incredible, thanks so much for taking the time. Every point here is useful!

just coding it yourself will both save space ... and save time

This is my instinct as well, so I'm using the opportunity to specifically leanr about JQuery - otherwise I expect it to feel frustrating at times.

Use .prop() instead of .attr() whenever you can.

Did not know this, thanks much.

you don't have to care if the specific element you want to match on even exists in the DOM when you add the event.

Hadn't thought of that, that's good to keep in mind.

methods will silently fail

How do you mitigate this? Explicit run-time checks?

there's no point in manually looping over the returned results

This is one I did "know" but still somehow didn't realize you could use this way. Awesome.

functionally idempotent and declarative

This I did not realize and am a huge fan of. Unless I'm missing it, I don't think the docs make this very clear, but thinking about it, of course that's how they work.

Had not heard of cash, I'll make the case! Looks pretty snazzily familiar, he may go for it.

Collapse
ahferroin7 profile image
Austin S. Hemmelgarn

Use .prop() instead of .attr() whenever you can.

Did not know this, thanks much.

Yeah, this one could stand to be covered more in a lot of jQuery tutorials. It's a regular source of subtle bugs as well as performance issues in code written by people who aren't familiar with jQuery.

methods will silently fail

How do you mitigate this? Explicit run-time checks?

I don't know what the norm is in big jQuery projects. For any of my stuff, I just make certain that things are strictly ordered such that this never happens (and when I can't ensure strict ordering, I use Arrive). FWIW, if you want to check, the most reliable approach is to check the length property of the returned jQuery object (if it's zero, nothing matched).

functionally idempotent and declarative

This I did not realize and am a huge fan of. Unless I'm missing it, I don't think the docs make this very clear, but thinking about it, of course that's how they work.

Yeah, the docs really don't make it clear, and while it kind of makes sense, it is inconsistent with how most programmers assume most things behave by default.

Had not heard of cash, I'll make the case! Looks pretty snazzily familiar, he may go for it.

Best time to go for it is when starting out. It's pretty easy to switch to jQuery after the fact if you need to, but not so much going the other way.

Thread Thread
deciduously profile image
Ben Lovy Author

most reliable approach is to check the length property of the returned jQuery object

That works for me - I don't think this project will qualify as "big". 1-2k lines of JS total. Hadn't seen arrive, that looks handy, but I think I'm going to see how I fare without it at first.

Seriously, this has been a huge help. You've boosted my confidence going in to this project, I feel a little less lost. Thanks again!