3

JavaScript:

parent.addEventListener("click", function(e) {
  if (e.target === child) { code }
});

vs.

jQuery:

$(parent).on("click", child, function() {});

Adam Zerner
  • 17,797
  • 15
  • 90
  • 156
  • 2
    The pure Javascript one is probably minutely more efficient because jQuery wraps the code in an "easy to write" manner, but the performance difference is negligible... plus the pure Javascript method doesn't have any library dependencies. – Kinnectus Jul 25 '14 at 21:07
  • jQuery does the exact same thing internally, it filters based on a selector, and it checks the event target and the parents for that selector, same thing you would do in plain JS. – adeneo Jul 25 '14 at 21:12

3 Answers3

4

Marginal, jQuery's on method does a bit more work to give you extra functionality, like running a selector as the event bubbles up to the root, so the event comes from the element you're expecting; if you're not careful, that could be problematic. Citing the documentation, under Event Performance:

Attaching many delegated event handlers near the top of the document tree can degrade performance. Each time the event occurs, jQuery must compare all selectors of all attached events of that type to every element in the path from the event target up to the top of the document.

Plain javascript on the other hand does something more straightforward, just raises any event that happened under that element, so you have to be very specific.

Having said that, the performance difference is negligible for modern engines under normal circumstances, like a few hundred event handlers.

However, as @Patrick points out, it could be disastrous for some special cases where you have thousands of elements you need to keep track of and get events from; running selectors in this case, for each event, will kill your performance. Sometimes you will benefit from using special techniques, like only attaching one event handler to the container of said elements and using e.target to find out what actually caused the event.

Jaime Gómez
  • 6,961
  • 3
  • 40
  • 41
  • The performance difference is negligible for small volume event handling, like you might find for DOM events, but for many events like you might find in a particle system, there is a significant difference. http://jsperf.com/jquery-events-vs-backbone-events-performance/3 – Patrick Gunderson Jul 25 '14 at 21:42
  • 1
    That's true, I added a mention for cases like that at the end :) – Jaime Gómez Jul 25 '14 at 21:47
1

The question suggests that those lines of code in JS and jQuery do the same, but they do not!

Thus, I split my answer into two parts:

1. Which JS/jQuery pair is actually doing the same and how do they perform?

# suggested JavaScript version
parent.addEventListener("click", function(e) {
  if (e.target === child) { code }
});

# correct equivalent jQuery version
$(parent).on("click", function(e) {
  if (e.target === child) { code }
});

Performance

Short: The performance difference is minimal and does not matter.

Long: Both versions almost look the same. The jQuery variant is a tiny bit slower, but that is negligible. I would use the jQuery version if I’m on a roll with jQuery (e.g. method chaining) or want to use jQuery for readability/consistency.

Using the JavaScript version for speed reasons while defending/promoting/advocating the use of jQuery in that project would be a conflict of interests.

2. What is the problem with OP’s jQuery line?

# OP’s version: jQuery selector/delegate syntax
$(parent).on("click", child, function() { code });
  • the implementation does not what you want or think
    • jQuery’s selector/delegate syntax does not what the OP thought it does
    • I fell for the same trap, you too?
  • it burns extra CPU cycles while doing the wrong thing
    • this performance penalty outranks by far the minor penalty of the correct jQuery version mentioned above
  • is ill documented
    • jQuery docs do not shed any light on the issue
    • docs nurture the believe that it does what most of us think it would
    • leads you to believe the “delegate syntax” is the only (right) way to delegate
  • it looks treacherously short and pretty
    • depending on the selector it will probably yield the same result in many cases
    • will a correct implementation get into jQuery?
      • will it use the same short syntax?

The rest of this answer is showing by example what jQuery does wrong:

I think we all agree that a single event should call the handler once at most. With the following code example I show you how a single event triggers 3 calls of the handler.

Click in the inner box to see how jQuery multiplies a single event for all matching elements between target and handler element. I don’t know a reasonable use case for such a mechanism, and even if this unexpected and strange behavior does not hit you, the extra work which jQuery does for it is still there.

It either has no effect and just burns CPU cycles or it creates a bug.

let lastEvent;
function analyze(tag, event) {
  const oe = event.originalEvent;
  console.log(`${tag}: Event on ${event.target.id} is ${lastEvent === oe ? 'repeated' : 'new'}.`);
  lastEvent = oe;
}

body.addEventListener('click', event =>
  console.log('click', event.target.id));
$(body).on('click', analyze.bind(null, '$click'));
$(body).on('click', '.hit', analyze.bind(null, '$delegateClick'));
div.hit {
  margin: 20px;
  border: solid black 2px;
}

#inner {
  height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body id=body>
  <div id=outer class=hit>
    <div id=middle class=hit>
      <div id=inner class=hit>
      </div>
    </div>
  </div>
</body>
Robert Siemer
  • 32,405
  • 11
  • 84
  • 94
  • I'm not positive I fully follow, but my initials thoughts are that you somewhat contrived the code example. To me, using the "correct syntax" above mostly means duplicating code I don't actually have to write if I use the selector/delegation syntax. I understand that the code you showed points a real potential issue with this - however, at least on the project sizes I work on, I haven't seen this becoming a noticeable issue. I'll gladly take the more concise (and overtime more readble?) syntax it offers. – logicOnAbstractions Oct 06 '21 at 11:54
  • @logicOnAbstractions The proper short term solution is to write a tiny jQuery extension providing a correct implementation of the “short syntax”.—Until I do that, I will keep my principle and categorically avoid buggy code no matter the code size. Because code that does something else than what it looks like is not “readable” in my book. – Robert Siemer Oct 06 '21 at 21:32
-2

According to this jsperf for event triggering performance it looks like jquery is significantly slower than both native and Backbone events. Backbone events are orders of magnitude faster than either jquery or navtive events.

Patrick Gunderson
  • 3,263
  • 17
  • 28