-
Notifications
You must be signed in to change notification settings - Fork 7
Make all event listeners passive where supported #4
Conversation
See [the passive event listener explainer](https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md). In practice we believe changing just this one script will have a measurable scroll performance improvement on the web.
Note that I haven't made any attempt to test this PR, and may even have stupid typos. But hopefully it's still helpful as a start. Chrome 51 (current dev channel on desktop and Android) supports this feature. |
@@ -85,9 +85,19 @@ limitations under the License. | |||
root.focused = false; | |||
}); | |||
|
|||
var supportsPassive = false; | |||
try { | |||
addEventListener("test", null, Object.defineProperty({}, 'passive', {get: function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RByers I'm having a hard time grokking this logic. I understand it's meant to determine whether the browser supports passive listeners, but I don't exactly see how it's doing that. Can you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's a little ugly / confusing, sorry about that. Basically the canonical way (only way at the moment) to feature detect for dictionary members is to pass a custom object to an API that takes the dictionary and see if the getter is invoked for the property of interest. WebIDL Ecmascript bindings require that the getter for each supported property is invoked when the function is called.
So in this case we do a dummy call to addEventListener
(passing null as the handler is defined to be a no-op). We pass into that a custom object whose passive
getter function just records that it has been called. There are four possible behaviors:
- Browser doesn't support
addEventListener
ordefineProperty
at all - throws,supportsPassive
remains false. addEventListener
expects only a boolean in the 3rd position. The object gets coerced to the valuetrue
without invoking the getter.supportsPassive
remains false.addEventListener
supports taking a dictionary in the 3rd position, but not thepassive
member. In that case other getters may be invoked, but not the one we've defined forpassive
.supportsPassive
remains false.addEventListener
supports the passive option. In that case the getter function we've defined gets run as part of the JavaScript API binding andsupportsPassive
will be true.
For context see the original design discussion and this WebIDL issue where we're considering exposing something less ugly.
Thanks for the pull request @RByers. This repository is meant only as a public mirror of code that we use internally at Parse.ly. We don't actually import or use this repository in any way, so merging your pull request won't change anything. However, this diff is very helpful as an example of how we can support passive listeners. I'll prioritize getting it into the tracker and testing it across different browsers. |
Thanks for looking at this! I understand regarding the role of this repo - feel free to close the PR. |
See the passive event listener explainer. In practice we believe changing just this one script will have a measurable scroll performance improvement on the web. Fixes #3.