Chrome did an "intervention" back in the day, breaking all React touch and wheel listeners which used e.preventDefault() (https://github.com/facebook/react/issues/14856) because React happened to attach them to the document.
In React 17, events are no longer attached to the document. This happens to "undo" Chrome's intervention (https://github.com/facebook/react/issues/6436#issuecomment-676135176). However, since this functionality is already broken in 16 and we haven't patched it up, it seems like this would just be a performance regression for the majority of cases.
It seems like we have a few options:
e.preventDefault() is broken, just like it got broken in 16 by Chrome.e.preventDefault().document level and not individual elements — and conceptually React users were putting their handlers on individual elements. Delegation is just an implementation detail.Filing this to be resolved before 17 final.
We briefly discussed with @sebmarkbage and since the goal of 17 is to be as close to 16 as possible (while fixing interop), we're going to emulate Chrome's behavior and treat these as passive by default when attaching to roots. This doesn't solve the usability issue but that's orthogonal to the 17 release and should not block it.
FYI, Firefox does the intervention as well.
https://www.fxsitecompat.dev/en-CA/docs/2018/touch-event-listeners-are-now-passive-by-default-making-scrolling-faster-on-mobile/
Is there a definitive list of affected events?
I take it, we have:
touchstarttouchmovewheelhttps://docs.google.com/document/d/1II7oSIpd8pK91V5kEM3tDLKcIj398jOJn8Niqy6_loI/edit
Anything else?
MDN has a list for this. (I'm not sure whether the list is definitive or not.)
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Browser_compatibility
Seems like it's just these four. (I excluded mousewheel because we don't use it.)
As far as the "do nothing" option is concerned: This seems like this is likely a bug in lighthouse (or otherwise it's a missing feature in react as per your first option).
The intervention claims to only effect window and document level events, for performance reasons.
If that's the case, then there isn't a negative performance implication for attaching mouse wheel and touch events to other elements. And if that's the case, then lighthouse shouldn't report it as a performance issue.
If that's not true, then indeed it's a missing react feature to not be able to mark an event as passive.
As far as "don't do delegation for effected events", I don't think that can address the problem.
The intervention claims to only effect window and document level events, for performance reasons.
This is correct.
If that's the case, then there isn't a negative performance implication for attaching mouse wheel and touch events to other elements.
In my understanding, there is still a performance implication. But doing it for direct bindings is just a more breaking change so they weren't able to do it.
Most helpful comment
We briefly discussed with @sebmarkbage and since the goal of 17 is to be as close to 16 as possible (while fixing interop), we're going to emulate Chrome's behavior and treat these as passive by default when attaching to roots. This doesn't solve the usability issue but that's orthogonal to the 17 release and should not block it.