-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Timing of <dialog>
'close' event, popover 'toggle' event, <details>
'toggle' event
#9046
Comments
<details>
'toggle' event<dialog>
'close' event, popover 'toggle' event, <details>
'toggle' event
Open UI resolution: Fire "closed" and "toggle" events in a microtask rather than a task (option 3 above) Minutes: https://www.w3.org/2023/03/23-openui-minutes.html#t02 |
I'd like @smaug---- to look at this as well and maybe @rniwa. I tend to agree that events for UI changes should happen before the next paint, but I'm not sure I fully understand the implications of using microtasks for a lot more things. |
@annevk I'd also like to hear more why a sync event is bad here. I agree it's a more compatible change for |
Do yall have any thoughts? I can make a spec PR and implement this in chrome, but it would be great to have your support beforehand |
microtasks were designed for this kind of case - MutationObserver callback should fire before the next rendering update. So, using microtasks also there sounds reasonable, and it is probably quite web compatible, since microtasks are kind of asynchronous from JS point of view (but synchronous from browser point of view). |
Thanks! I'll go ahead with this change then |
I created a PR to switch to microtasks: #9775 |
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
Instead of firing the async popover toggle events using a regular task, they should be fired at microtask timing to be faster. As suggested in the issue, this patch also uses microtasks for the dialog element's close event and the details element's toggle event: whatwg/html#9046 I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/9R5Zedd1-LE Bug: 1485980 Change-Id: I70569a36e6447283a5101117693d235020ebb4a6
When I look at "show popover" (and "hide popover") we already fire Edit: I guess the main thing is that if it happened multiple times you get some deduplication, but is that still true enough with microtasks? And meaningful enough given that cc @domenic |
Yeah I suppose there isn't as much value for popovers given beforetoggle. Details elements don't have beforetoggle though.
This is one of the main value points as I see it - it would simply make the events more consistent, right? I'm not sure how much this applies to other events in the platform though. |
To be clear, I think overall changing our approach here makes sense. I'm just discussing the details to make sure we don't want to change this again a couple years down the road.
Thoughts? |
I'd like to keep popover, details, and dialog on the same timing if at all possible. |
I think |
I agree with domenic that we should keep them all the same, and I don't think that making any of them synchronous instead of async or microtask would be great. The fact that the beforetoggle event for popovers is synchronous (which it has to be in order for it to be useful) has caused us to add a lot of extra logic to handle what happens when the state is changed in the event handler. Maybe the toggle and close events aren't subject to that, but I don't see the value in making them synchronous instead of microtask.
The cancel event is already synchronous right...? We should keep it that way so that preventing the closing of dialogs still works, right? |
If I can attempt to move towards a consensus:
Does this sound suitable to everyone? |
This works for me, but the compat impact means implementers need to be the ones making the call. I will say that having dialog cancel and close have the same timing is nice. Their different timing (cancel sync, close async) caused some pain with the close watcher integration. |
If yall really want to make dialog close synchronous, then I'll do it carefully with a flag and go back on it if it breaks websites. I feel more confident that that moving things from slow task queueing to microtasks won't have compat issues - although I'm still going to ship that behind a flag and undo it if it breaks websites as well. |
There are use cases for an async Further, since these events can't prevent the default action there is not a reason they have to be synchronous. Therefore, I think we should leave them async but consider extensions to |
Since all of the options are (by design) before the next paint, they're all equally blocking in terms of UX. 500ms of JS execution will feel the same whether it's immediate, microtask, or render steps. |
I agree that if the developer needs it to block paint, a delay is inevitable if script runs long. My main point is that the default being async is a good thing, for those developers who don't need it to block paint. |
This doesn't really make sense. Event listeners are called synchronously when the event is dispatched. There is not concept of asynchronousness there, nor concept of priority. |
I'm suggesting we add the ability for them to be async and have a priority. I agree that these would be new. |
https://html.spec.whatwg.org/multipage/popover.html
https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element
https://html.spec.whatwg.org/multipage/interactive-elements.html#details-notification-task-steps
The show/hide steps for these happen on the same thread. However, a task is queued to fire the
"close"
and"toggle"
events on dialog and popovers respectfully.This creates a weird situation where the event could fire before or after the next render. Given that "I'm here now!" events are often used by developers as a time to enhance elements, this creates a race condition where the original state may be seen for a frame - a flash of unenhanced content. This would be really difficult to debug.
The solution in the
<dialog>
/<details>
case would be to instead use a mutation observer for theopen
attribute, since that's guaranteed to happen before rendering. With popover, I guess you could use the"beforetoggle"
event, but this event is also cancellable, so it isn't exactly "I'm here now!".Option 1: Do nothing
Accept that it's a rotten bit of the platform, that will grow, since new features (like popover) will copy the behaviour in the name of consistency.
'select' events on various inputs also queue in this way.
Option 2: Dispatch the event synchronously
This is usually how events work when the action is performed on the main thread.
However, I think there's some reluctance to do this for
<dialog>
and<details>
, since it's related to an attribute change, and for some reason we don't want to fire events in relation to DOM changes?Also, changing from async to sync might be a compat risk for
<dialog>
and<details>
.Option 3: Dispatch the event in a microtask
This is how mutation observers work, which are related to DOM changes. It also allows for some debouncing, and it's still async.
Option 4: Dispatch the event in the render steps
This is how resize/scroll/pointer events work.
However, if the dialog is shown after this point in the render steps, you'd still get a flash of unenhanced content.
My preference is for option 2 or 3.
I can't decide if
"input"
events behave this way. The HTML spec suggests it might, but the UI events spec says it must be dispatched immediately.The text was updated successfully, but these errors were encountered: