Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
Plus most real-world cases are way too complex to be able to statically determine. Eg. People love their event delegation patterns. Try stepping through a no-op listener (eg. Click on whitespace) in gmail some time... On Jul 12, 2015 1:12 PM, Domenic Denicola d...@domenic.me wrote: Generally nobody wants to write code in their JavaScript engine implementation that is aware of concepts like the DOM, events, methods specifically named preventDefault, etc. -Original Message- From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Ashley Gullen Sent: Sunday, July 12, 2015 12:47 To: Rick Byers Cc: wha...@whatwg.org Subject: Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance Is it not possible for Javascript engines to statically determine if preventDefault() is called by an event handler? For example: function myHandler(e) { // does e.preventDefault occur anywhere in this body? }; target.addEventListener(scroll, myHandler); If none of the added event handlers reference the preventDefault property of their first parameter, then the browser engine could optimise knowing that preventDefault is never called. Then the developer does not need to specify a flag, and no APIs need to be altered. Since Javascript is dynamic it's not possible to tell exactly every time, e.g. given the statement e[some_string_variable](), that could resolve to a call to e[preventDefault]() at runtime. This means really there are three cases: 1. Yes: statically references e.preventDefault 2. Maybe: some dynamic reference like e[str] 3: No: no dynamic references, and no static references to e.preventDefault Assuming the maybe case is rare, then it could be conservatively treated as yes. Then for most reasonable real-world cases, you have a way to optimise scroll events without using any more information from the developer. A simple way to determine the no case could be to identify handlers with no parameters at all, e.g: function myHandler() // no parameter { // ... }; ...certainly cannot access e.preventDefault(), because it does not use the event in its parameters. (The function also should not reference arguments at all.) I don't know if libraries typically need the event for any other purposes, but this seems like at least one straightforward way for the developer to indicate I won't call preventDefault() without any new API. Ashley On 8 July 2015 at 20:12, Rick Byers rby...@chromium.org wrote: [Cross-posted to www-...@w3.org - please let me know if there's a better way to account for the DOM spec duality] In Chromium we've long worked hard at maximizing scroll performance, with scroll-blocking DOM events (wheel and touchstart in particular) being by far the biggest source of scroll jank. I've been talking about this problem off-and-on for several years with various folks including the Pointer Events Working Group, engineers of other browser vendors, and engineers working on popular libraries that are a source of such scroll-blocking event handlers (eg. Google Ads and Google Analytics). I've now written a relatively formal (but still sloppy by W3C standards) concrete spec for extending the DOM event model http://rbyers.github.io/EventListenerOptions/EventListenerOptions.htm l to address this problem and would like to solicit feedback. It's probably most constructive to discuss specific issues on GitHub https://github.com/RByers/EventListenerOptions/issues, but I'd appreciate any high-level feedback here by e-mail too. Please feel free to submit pull requests for eg. editorial improvements. Once there's a bit more consensus on the API shape, I plan to write a polyfill and tests and then begin a prototype implementation in Chromium. We have some initial evidence to believe that this (in partnership with a few key library authors) can make a substantial improvement to the user experience on mobile. I hope to be able to share more concrete data on the real-world performance impact, but there's obviously a chicken and egg problem here. Thanks, Rick
Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
On Sat, Jul 11, 2015 at 11:41 PM, Rick Byers rby...@chromium.org wrote: What Anne describes is perfect! I'm not hung up on the value of cancelable itself - some internal bit on Event that makes preventDefault a no-op (or event throw) during listener invocation is fine with me (and I agree - less weird). If code really wants to test whether it's call to preventDefault took effect, it can check defaultPrevented afterward. No, that is not what I said. I said we'd disable preventDefault() for the listeners that have this bit set. If all listeners for a given event have the bit said, the UA can make the optimization. (And the setTimeout() example is perfectly deterministic. It changes the canceled flag, but after that flag has been consulted by the dispatcher.) -- https://annevankesteren.nl/
Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
On Sat, Jul 11, 2015 at 11:40 PM, Anne van Kesteren ann...@annevk.nl wrote: On Sat, Jul 11, 2015 at 11:41 PM, Rick Byers rby...@chromium.org wrote: What Anne describes is perfect! I'm not hung up on the value of cancelable itself - some internal bit on Event that makes preventDefault a no-op (or event throw) during listener invocation is fine with me (and I agree - less weird). If code really wants to test whether it's call to preventDefault took effect, it can check defaultPrevented afterward. No, that is not what I said. I said we'd disable preventDefault() for the listeners that have this bit set. If all listeners for a given event have the bit said, the UA can make the optimization. [...] This is what I had in mind as well. Also it occurs to me there's a missing primitive here for how the browser knows that all listeners have mayCancel: false so it can make this optimization. EventTarget needs some kind of method like: boolean hasOnlyPassiveEventListeners(DOMString type) so the scroll system can query if all listeners have mayCancel: false to make the optimization. Adding this also has the advantage of making it easy to feature detect if the browser supports this, just look to see if the hasOnlyPassiveEventListeners property exists on Node. - E
Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
On 7/12/15 12:47 PM, Ashley Gullen wrote: 1. Yes: statically references e.preventDefault 2. Maybe: some dynamic reference like e[str] 3: No: no dynamic references, and no static references to e.preventDefault Assuming the maybe case is rare Is there data supporting this assumption? I would expect that in practice in the cases that matter the maybe case is the common one. In particular, I expect that the maybe case includes the following situations: 1) someObject[someName].call(event); 2) someFunctionThatIsNotInlined(event); 3) event[someName](); Of these, I expect #2 to be the most common, then #1, then #3... and I expect #2 to be _very_ common. A simple way to determine the no case could be to identify handlers with no parameters at all, e.g: Are these common in the case of the events we're talking about here? (Also, that's assuming window.event doesn't exist, and while that assumption is kinda ok today if you're writing cross-browser code that may cease being the case in the near future if Gecko ends up having to implement window.event.) -Boris
Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
Is it not possible for Javascript engines to statically determine if preventDefault() is called by an event handler? For example: function myHandler(e) { // does e.preventDefault occur anywhere in this body? }; target.addEventListener(scroll, myHandler); If none of the added event handlers reference the preventDefault property of their first parameter, then the browser engine could optimise knowing that preventDefault is never called. Then the developer does not need to specify a flag, and no APIs need to be altered. Since Javascript is dynamic it's not possible to tell exactly every time, e.g. given the statement e[some_string_variable](), that could resolve to a call to e[preventDefault]() at runtime. This means really there are three cases: 1. Yes: statically references e.preventDefault 2. Maybe: some dynamic reference like e[str] 3: No: no dynamic references, and no static references to e.preventDefault Assuming the maybe case is rare, then it could be conservatively treated as yes. Then for most reasonable real-world cases, you have a way to optimise scroll events without using any more information from the developer. A simple way to determine the no case could be to identify handlers with no parameters at all, e.g: function myHandler() // no parameter { // ... }; ...certainly cannot access e.preventDefault(), because it does not use the event in its parameters. (The function also should not reference arguments at all.) I don't know if libraries typically need the event for any other purposes, but this seems like at least one straightforward way for the developer to indicate I won't call preventDefault() without any new API. Ashley On 8 July 2015 at 20:12, Rick Byers rby...@chromium.org wrote: [Cross-posted to www-...@w3.org - please let me know if there's a better way to account for the DOM spec duality] In Chromium we've long worked hard at maximizing scroll performance, with scroll-blocking DOM events (wheel and touchstart in particular) being by far the biggest source of scroll jank. I've been talking about this problem off-and-on for several years with various folks including the Pointer Events Working Group, engineers of other browser vendors, and engineers working on popular libraries that are a source of such scroll-blocking event handlers (eg. Google Ads and Google Analytics). I've now written a relatively formal (but still sloppy by W3C standards) concrete spec for extending the DOM event model http://rbyers.github.io/EventListenerOptions/EventListenerOptions.html to address this problem and would like to solicit feedback. It's probably most constructive to discuss specific issues on GitHub https://github.com/RByers/EventListenerOptions/issues, but I'd appreciate any high-level feedback here by e-mail too. Please feel free to submit pull requests for eg. editorial improvements. Once there's a bit more consensus on the API shape, I plan to write a polyfill and tests and then begin a prototype implementation in Chromium. We have some initial evidence to believe that this (in partnership with a few key library authors) can make a substantial improvement to the user experience on mobile. I hope to be able to share more concrete data on the real-world performance impact, but there's obviously a chicken and egg problem here. Thanks, Rick
Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior
On Fri, Jul 10, 2015 at 1:54 PM, Majid Valipour maji...@chromium.org wrote: On Mon, Jun 29, 2015 at 5:20 PM Jonas Sicking jo...@sicking.cc wrote: FWIW I still prefer an API like history.scrollRestoration = 'manual'; The main reason is that it seems to me that pushState/replaceState has a largely orthogonal set of use cases that it tries to address from scroll restoration. So I suspect that grouping the two together will create awkwardness in the API in the future. But I don't have time to chase this issue. / Jonas Jonas, After some offline discussion with Rick, we have decided to converge to your preferred API. I hope this addresses your concern about potential future awkwardness and help make adoption easier. I have updated the proposed spec to reflect this change. The semantic of history.options.scrollRestoration is based on our previous discussion in this thread [1]. It short, it does not change any previous entries and navigating across documents resets its value so it only applies to entries created for the same document. Minor bikeshed: I have put scrollRestoration on history.options instead of directly history itself in order to use history.options as an interface to contain any other restoration related attributes which have similar semantics (e.g., recorder scroll position, scale restoration, recorded scale). Thanks Majid! This sounds great! / Jonas
Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance
Generally nobody wants to write code in their JavaScript engine implementation that is aware of concepts like the DOM, events, methods specifically named preventDefault, etc. -Original Message- From: whatwg [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Ashley Gullen Sent: Sunday, July 12, 2015 12:47 To: Rick Byers Cc: wha...@whatwg.org Subject: Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance Is it not possible for Javascript engines to statically determine if preventDefault() is called by an event handler? For example: function myHandler(e) { // does e.preventDefault occur anywhere in this body? }; target.addEventListener(scroll, myHandler); If none of the added event handlers reference the preventDefault property of their first parameter, then the browser engine could optimise knowing that preventDefault is never called. Then the developer does not need to specify a flag, and no APIs need to be altered. Since Javascript is dynamic it's not possible to tell exactly every time, e.g. given the statement e[some_string_variable](), that could resolve to a call to e[preventDefault]() at runtime. This means really there are three cases: 1. Yes: statically references e.preventDefault 2. Maybe: some dynamic reference like e[str] 3: No: no dynamic references, and no static references to e.preventDefault Assuming the maybe case is rare, then it could be conservatively treated as yes. Then for most reasonable real-world cases, you have a way to optimise scroll events without using any more information from the developer. A simple way to determine the no case could be to identify handlers with no parameters at all, e.g: function myHandler() // no parameter { // ... }; ...certainly cannot access e.preventDefault(), because it does not use the event in its parameters. (The function also should not reference arguments at all.) I don't know if libraries typically need the event for any other purposes, but this seems like at least one straightforward way for the developer to indicate I won't call preventDefault() without any new API. Ashley On 8 July 2015 at 20:12, Rick Byers rby...@chromium.org wrote: [Cross-posted to www-...@w3.org - please let me know if there's a better way to account for the DOM spec duality] In Chromium we've long worked hard at maximizing scroll performance, with scroll-blocking DOM events (wheel and touchstart in particular) being by far the biggest source of scroll jank. I've been talking about this problem off-and-on for several years with various folks including the Pointer Events Working Group, engineers of other browser vendors, and engineers working on popular libraries that are a source of such scroll-blocking event handlers (eg. Google Ads and Google Analytics). I've now written a relatively formal (but still sloppy by W3C standards) concrete spec for extending the DOM event model http://rbyers.github.io/EventListenerOptions/EventListenerOptions.htm l to address this problem and would like to solicit feedback. It's probably most constructive to discuss specific issues on GitHub https://github.com/RByers/EventListenerOptions/issues, but I'd appreciate any high-level feedback here by e-mail too. Please feel free to submit pull requests for eg. editorial improvements. Once there's a bit more consensus on the API shape, I plan to write a polyfill and tests and then begin a prototype implementation in Chromium. We have some initial evidence to believe that this (in partnership with a few key library authors) can make a substantial improvement to the user experience on mobile. I hope to be able to share more concrete data on the real-world performance impact, but there's obviously a chicken and egg problem here. Thanks, Rick
Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior
On Sun, Jul 12, 2015 at 7:49 PM, Jonas Sicking jo...@sicking.cc wrote: I think we've already made that assumption given that history.state already relies on this. Good point. I'm still somewhat skeptical of introducing new objects just for the purpose of grouping some properties if they don't serve a purpose on their own. -- https://annevankesteren.nl/
Re: [whatwg] Proposal: Allow disabling of default scroll restoration behavior
On Sat, Jul 11, 2015 at 10:51 AM, Anne van Kesteren ann...@annevk.nl wrote: On Fri, Jul 10, 2015 at 10:54 PM, Majid Valipour maji...@chromium.org wrote: Minor bikeshed: I have put scrollRestoration on history.options instead of directly history itself in order to use history.options as an interface to contain any other restoration related attributes which have similar semantics (e.g., recorder scroll position, scale restoration, recorded scale). Is the History object Document-bound in all implementations? Otherwise adding new dependent objects will be problematic security-wise. I think we've already made that assumption given that history.state already relies on this. / Jonas