Attaching multiple handlers to an event and allowing asynchronous event handlers #60574
Replies: 6 comments 17 replies
-
Hi @westonruter 👋 . The possibility of using multiple event listeners for the same event sounds essential. The current problem is that we cannot have two identical properties in the same HTML element, as you mentioned. <div data-wp-context='{ "isOpen": true }'>
<button
data-wp-on--click="actions.someAction"
data-wp-on--click="analytics::actions.track" <!-- duplicated attribute: won't work -->
>Click</button>
</div> A possibility would be to extend the current <div data-wp-context='{ "isOpen": true }'>
<button
data-wp-on--click="actions.someAction"
data-wp-on--analytics='{ "event": "click", "callback": "analytics::actions.track", "async": true, "passive": true }'
>Click</button>
</div> That would be a substantial change to the API, with the suffix being either an event type or a unique ID, and could cause some confusion. I'm open to exploring that, though. 😄 Maybe we could create another directive for more complex event listener definitions like you proposed. 🤔 PS: Another possibility: append the ID after the suffix with the event type. <div data-wp-context='{ "isOpen": true }'>
<button
data-wp-on--click="actions.someAction"
data-wp-on--click--analytics='{ "callback": "analytics::actions.track", "async": true, "passive": true }'
>Click</button>
</div> |
Beta Was this translation helpful? Give feedback.
-
Would an array form of the <!-- simple -->
<button data-wp-on--click="actions.clickHandler">X</button>
<!-- multiple -->
<button data-wp-on--click='["actions.clickHandler", "analytics::actions.trackClick"]'>X</button> |
Beta Was this translation helpful? Give feedback.
-
I don't think an array would be a suitable solution, since different plugins need to be able to add e.g. "click" listeners to the same element. So it wouldn't be a good DX to have to modify an existing attribute, change it from string to array, etc.
That would be a great solution IMO. It ties in nicely with the existing approach on |
Beta Was this translation helpful? Give feedback.
-
Let's say it's settled that multiple actions can be attached to an event, whether it is via a unique ID suffix or some array syntax. The question then remains how we can safeguard performance. And that's the second part of the discussion topic. There should be a way to register an action for an event which can be run entirely asynchronously. Related to this is the docs on async actions and the use of generators as actions. The async actions there are those which run synchronously and then allow for an asynchronous break in execution (e.g. to perform a One way to do this would be to introduce some import { store, mainThread } from '@wordpress/interactivity';
store( "myPlugin", {
actions: {
*trackClick() {
yield mainThread();
// Now do tracking logic...
},
},
} ); This would be a useful tool in the toolbox for tuning the performance of actions regardless (e.g. to break up a computationally-expensive action), but it's yet another thing that a developer has to know. Ideally such actions could be asynchronous by default so that a manual |
Beta Was this translation helpful? Give feedback.
-
Closing this as completed 🙂 |
Beta Was this translation helpful? Give feedback.
-
In thinking about use cases for the Interactivity API, a common use case for scripting in general on the web is for analytics (for better or worse) to track interactions. Given the following interactive block from the examples, how would a 3rd party plugin attach a click event handler to send off the number of times that the button was clicked to some analytics backend?
Unlike with the
wp-init
directive, it does not appear that multiplewp-on
directives can be added with a unique ID to differentiate them (as the event name plays this role). Is there a way for another plugin, such as with the Tag Processor, to inject additional event handlers to run? (Other than to attach the event handler manually inwp-init
?)In particular the Performance team here is concerned about enforcing best practices for... performance. 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. This very frequently results in a long task that hurts INP. If multiple events handlers are supported for a
wp-on
directive (as it seems they should be) then there should be a way to ensure that they run asynchronously unless they absolutely need synchronous access to theevent
object (such as to callpreventDefault()
). This will allow the Interactivity API to yield to the main thread before invoking each event handler, if declared as asynchronous. (Relatedly, the Interactivity API should allow for event handlers to be passive: #58705).Beta Was this translation helpful? Give feedback.
All reactions