Support for passive event handlers
bennycode opened this issue · 14 comments
Chrome 51 introduced passive event handlers. Maybe the performance of jquery-mousewheel can be improved with this:
Read more:
Because I sometimes get this when using jquery.mousewheel.js
:
Handling of 'wheel' input event was delayed for 730 ms due to main thread being busy. Consider marking event handler as 'passive' to make the page more responive.
Can you create a simple example on jsfiddle.net or jsbin.com (or other favorite code sample site) that recreates the problem?
I wasn't aware than any events other than touch events support passive yet.
Maybe things can be improved, but we'd need some tests to show that it does and also to show that the plugin still works on all browsers it supports.
How do you know the event handler won't invoke preventDefault()? Only then
you can use a passive listener and I suspect many uses of this plugin are
about disabling or modifying native scroll.
Michał Gołębiowski
I agree with @mgol here. In any case the underlying jQuery APIs don't yet support passive listeners so it would be difficult to do so for this plugin right now.
Looks like this issue on core will enable this plugin to move forward on this: jquery/jquery#2871
why it is so difficult to pass a single boolean to native api?
How do you know the event handler won't invoke preventDefault()?
Because developer knows what he does in event handler. It's not some-unknown handler. If developer requests passive handling, he knows why he requests it.
It will be a half of year soon. It looks simpler to drop jquery than to wait for new features. :/ Sad
why it is so difficult to pass a single boolean to native api?
It's not that simple. jQuery has its own event handling (which was needed to workaround many browser bugs); if you attach two click
handlers to the same element, jQuery uses addEventListener
only once; it attaches its own meta-handler that dispatches event handlers in the correct order. Since the browser only sees one event handler, it's not possible to attach one handler with the passive flag and another one without it. Adding support for passive event listeners would require exactly that. Therefore, this is not possible without a deep refactor of the jQuery internal event implementation (which we plan to do for jQuery 4 or later).
It looks simpler to drop jquery than to wait for new features. :/
We're all unpaid volunteers mostly working on jQuery in our free time and deep refactors take a lot of time. It's not that easy to fix this issue.
it's not possible to attach one handler with the passive flag and another one without it.
why do you imagine the problem that don't exists?
any active handler will block queue, so it's not an option for developer to mix passive with active.
since the whole purpose of passive handling is to reduce delays for events which do not affect rendering
any active handler will block queue, so it's not an option for developer to mix passive with active.
You might not control all the code in your application. A separate module may attach a non-passive listener (and e.g. detach it shortly afterwards, thus not influencing app performance in a big way) before or after you attach your passive one; what would you expect to happen then?
We're open to look for alternate, simpler solutions but those are the types of dilemmas that need to be taken into account.
what would you expect to happen then?
i do not expect any specific order required for a separate module. it is very specific case where order would matters.
I'm asking what would you expect to happen with the passive flag then in both of those cases: if other code attaches a non-passive listener after you attach a passive one or vice versa (taking into account the fact that in both cases the browser will only get one real handler attached).
2 queues in one handler - all passive first will be ok for me.
but i think 2 handlers with separate queues would be better
Order matters only in case of using stopImmediatePropagation, the usage of it is extremely rare.
stopPropagation affect different elements
preventDefault does not affect user handlers
Order may not matter to you but it doesn't mean it matters to no one else. Native handlers maintain the order and we do as well. Breaking that assumption is not an option for us, especially that we plan a big refactor of the event system (that will allow to support passive handlers among other things) and we'd then change that behavior back to following the spec order.
Any change we make creates situations where people depend on the new behavior. Each time breaking that has to be preceded by careful thinking if benefits trump the drawbacks. Therefore, planning a breaking change that both takes us away from the spec and that we plan to revert back in the next version is not an attractive option for us.
On the other hand, if you think you need it right now, it's very easy to hack it in the jQuery copy you use where the constraints described by me above don't have to be met. Just edit the line at https://github.com/jquery/jquery/blob/3.1.1/src/event.js#L193, changing it to (not tested):
if ( isPassive( elem, type ) ) {
elem.addEventListener( type, eventHandle, {passive: true} );
} else {
elem.addEventListener( type, eventHandle );
}
where you can define isPassive
to follow whatever logic you need.