-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Event directives can only be synchronous without the option for them to be asynchronous/passive #61634
Comments
wp-on-async
directive as performant alternative over synchronous wp-on
directive
Here's a PR with the proposed changes: #61885 |
I had an idea to make It would work as follows. Instead of adding The only downside would be that, until several WordPress versions later, |
A couple challenges here are that (1) this requires the user to trigger the event to see the warning, and (2) calling |
Let's use |
Reopening as we should also now leverage |
Great idea to use this for core blocks! Maybe open a new issue for this since this Issue seems to be resolved? |
I guess so. It's just the initial PR implemented |
I've opened #62160 to implement |
Please see discussion in #60574 (comment).
Interactivity performance on the web is heavily impeded by too many event handlers running synchronously in response to a user interaction. This is made evident by poor responsiveness on web pages which is also reflected in poor Interaction to Next Paint (INP) scores. Too much JavaScript running at once results in long tasks (>50ms) which a user can experience as jank (e.g. stuttering animations) or worse: rage clicks. To help guard against this as much as possible, event handlers should be broken up into chunks, each of which take less than 50 ms to complete on modest hardware. Nevertheless, even if one event handler is doing its part to take less than 50 ms, if there are multiple event handlers which are also running (and which may be less than 50 ms), it is most likely that they will all add up to a long task that hurts the user experience. (This is a real possibility as of #60661.)
The issue is that by default an event handler runs synchronously and blocks the main thread. In the Interactivity API, this is the
wp-on
directive. Sometimes an event handler must be synchronous in order to be able to callevent.preventDefault()
. However, for many use cases there is no need for synchronous access. For example, a common problem on the web is that analytics trackers will attach their event handlers that run synchronously at the same time as critical 1st party code. These should be safely made asynchronous. The majority of directives in the Image block can also be made asynchronous, particularly those which don't callevent.preventDefault()
:data-wp-on--click
actions.hideLightbox
data-wp-on--click
actions.showLightbox
data-wp-on--keydown
actions.handleKeydown
data-wp-on--load
callbacks.setButtonStyles
data-wp-on--touchend
actions.handleTouchEnd
data-wp-on--touchmove
actions.handleTouchMove
data-wp-on--touchstart
actions.handleTouchStart
data-wp-on-window--resize
callbacks.setButtonStyles
data-wp-on-window--resize
callbacks.setOverlayStyles
data-wp-on-window--scroll
actions.handleScroll
As for implementation, it could look very similar to the existing
data-wp-on
directive logic but simply adding in a statement to yield before invoking each handler:As discussed in #60574 (comment), having such a
yieldToMain()
helper function would be useful for actions and callbacks to manually insert their own yield points before or after some expensive logic. For an example implementation ofyieldToMain()
, see Optimize long tasks, which was already implemented in the Interactivity API during hydration in #58227.Eventually once Preact supports
passive
event listeners (#58705), such async event handlers could be made passive as well.Once this is implemented, the core blocks can be updated to use
data-wp-async
instead ofdata-wp
. Additionally, @luisherranz noted in #60574 (reply in thread), the Interactivity API docs should be updated to make use of this directive whenever possible, and the create-block template can be updated to use it as well.The text was updated successfully, but these errors were encountered: