Re: [whatwg] DOM Events Proposal: EventListenerOptions 'mayCancel' for improved scroll performance

2015-07-12 Thread Rick Byers
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

2015-07-12 Thread Anne van Kesteren
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

2015-07-12 Thread Elliott Sprehn
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

2015-07-12 Thread Boris Zbarsky

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

2015-07-12 Thread Ashley Gullen
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

2015-07-12 Thread Jonas Sicking
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

2015-07-12 Thread Domenic Denicola
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

2015-07-12 Thread Anne van Kesteren
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

2015-07-12 Thread Jonas Sicking
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