JavaScript:
parent.addEventListener("click", function(e) {
if (e.target === child) { code }
});
vs.
jQuery:
$(parent).on("click", child, function() {});
JavaScript:
parent.addEventListener("click", function(e) {
if (e.target === child) { code }
});
vs.
jQuery:
$(parent).on("click", child, function() {});
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.
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:
# 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 }
});
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.
# OP’s version: jQuery selector/delegate syntax
$(parent).on("click", child, function() { code });
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>
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.