Optimizing yielding prior to actions out of the box #64729
Replies: 3 comments 32 replies
-
@luisherranz Related to your comment #61634 (comment). |
Beta Was this translation helpful? Give feedback.
-
I commented in the Slack channel, but my thoughts are very similar to Luis's.
|
Beta Was this translation helpful? Give feedback.
-
Resharing the approach I shared here, as it still might be worth considering: 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, |
Beta Was this translation helpful? Give feedback.
-
Over the past few months, the Interactivity API was enhanced with several
data-wp-on-async*
directives (see #61885), which allow invoking actions asynchronously, i.e. yielding to the main thread prior to execution the action, which helps performance by avoiding contention.First of all, it's worth clarifying that asynchronous actions and the
data-wp-on-async
directives are separate concepts, even though they are somewhat related:data-wp-on-async
directives will additionally yield to the main thread before even starting to run the action. The critical consideration here is that this is only reasonable if the action does not make use of certain synchronousevent
methods, such asevent.preventDefault()
orevent.stopPropagation()
.data-wp-on
ordata-wp-on-async
, as long as the action does not use one of those synchronous event methods. If it does, you must usedata-wp-on
.The purpose of this discussion is focused mostly on the yielding prior to executing an action, i.e. the functionality enabled by the
data-wp-on-async
directives.Current problems
While the
data-wp-on-async
approach is a decent start in preparing the Interactivity API to be more responsible about competing interactions, it currently puts the onus unnecessarily on the developers consuming the store, i.e. the ones that write the HTML containing the directives. It has a few drawbacks:data-wp-on-async
or not purely depends on whether the action does not use one of the synchronous event methods. So it is not a great DX to have to know about whether this is the case for each action as the developer writing the HTML directive.data-wp-on-async
so that it yields to the main thread prior to executing. So this makes it questionable why the person writing the HTML directive even needs to consider this at all.data-wp-on
anddata-wp-on-async
is complicated to understand for people not terribly familiar with JavaScript. I believe one of the value propositions of the Interactivity API is that in principle it can allow adding interactivity even without writing any JavaScript (if consuming actions from a reusable store from somewhere else, e.g. something core provides, or a 3P package). Having these two directives is IMO unreasonably complex from that perspective, which most likely will lead to a large portion of people usingdata-wp-on
in the long run because they don't understand when to usedata-wp-on-async
.data-wp-on
will probably be used by more folks (if in doubt), it will lead to a lot of unnecessary synchronous action calls.Proposed solution
The overall idea is the following: Whether an action can be called after yielding to the main thread or whether it must be called immediately is purely dependent on the action implementation, so it should be on the developer implementing the action in the store rather than the developer using it.
One important consideration: It is not reasonably possible for the Interactivity API to automatically detect whether an action calls a synchronous event methods or not. Therefore, the developers has to explicitly clarify that themselves.
This leads to the following concrete proposal:
data-wp-on
ordata-wp-on-async
and instead automatically make the right decision:data-wp-on-async
was used.data-wp-on
was used.data-wp-on-async
directives should be deprecated too in favor of all actions being annotated and thus allowing the Interactivity API to make the right decision automatically.Proof of concept example
Just a quick example to illustrate what this could look like (let's not get hung up on function names/signatures for now):
Interactivity API code example:
Store example:
Directive example:
I discussed this with @westonruter earlier this week, and we believe such an approach would lead to a much better long-term performance outcome, while simplifying the complexity by directly connecting the decision how to call the action with its implementation and decoupling it from directives.
Curious to get feedback on this proposal and shape this further.
Beta Was this translation helpful? Give feedback.
All reactions