w3c / long-animation-frames

Long Animation Frame API specification repository
Other
8 stars 1 forks source link

pauseDuration is 0 while synchronous dialogs are shown #17

Open rviscomi opened 1 month ago

rviscomi commented 1 month ago

According to MDN, pauseDuration represents:

the total time, in milliseconds, spent by the script on "pausing" synchronous operations (for example, Window.alert() calls or synchronous XMLHttpRequests)

However, script entries have a pauseDuration of 0, even while an alert is open.

Example LoAF entry ```json { "name": "long-animation-frame", "entryType": "long-animation-frame", "startTime": 4816.9000000059605, "duration": 4081, "navigationId": "ddfd6f3a-9257-457e-99ff-b67f267b1c31", "renderStart": 8898.40000000596, "styleAndLayoutStart": 8898.5, "firstUIEventTimestamp": 4878.700000017881, "blockingDuration": 3967, "scripts": [ { "name": "script", "entryType": "script", "startTime": 4831.5, "duration": 302, "navigationId": "ddfd6f3a-9257-457e-99ff-b67f267b1c31", "invoker": "TimerHandler:setTimeout", "invokerType": "user-callback", "windowAttribution": "self", "executionStart": 4831.5, "forcedStyleAndLayoutDuration": 0, "pauseDuration": 0, "sourceURL": "https://inp-demo-dialog.glitch.me/main.js", "sourceFunctionName": "periodicBlock", "sourceCharPosition": 1403 }, { "name": "script", "entryType": "script", "startTime": 5134.700000017881, "duration": 3763, "navigationId": "ddfd6f3a-9257-457e-99ff-b67f267b1c31", "invoker": "BUTTON.onclick", "invokerType": "event-listener", "windowAttribution": "self", "executionStart": 5134.700000017881, "forcedStyleAndLayoutDuration": 0, "pauseDuration": 0, "sourceURL": "https://inp-demo-dialog.glitch.me/", "sourceFunctionName": "onclick", "sourceCharPosition": 0 } ] } ```

Example trace: https://trace.cafe/t/GBb9saklW7

To reproduce:

  1. Open DevTools and go to https://inp-demo-dialog.glitch.me/
  2. Set blocking frequency to "Often"
  3. Trigger an alert
  4. Inspect the LoAF entry in the console

(You may need to try again if your interaction was < 50ms)

https://github.com/user-attachments/assets/68c3e356-e757-47c5-b4ee-9db8d42347a4

mmocny commented 1 month ago

I think that the setTimeout is expected to be 0 here, and the event-listener is expected to be non-0 here (assuming you called alert() directly from the event listener)

rviscomi commented 1 month ago

That's right, here's the button source:

<button onclick="alert('This no longer blocks INP as of Chrome 127! 🎉')">
  Alert
</button>
mmocny commented 1 month ago

Ah, I know there are some oddities with inline scripts and LoAF. If you changed to use addEventListener would it be any different?

rviscomi commented 1 month ago

Updated:

loafAlert.addEventListener('click', () => {
  alert('This no longer blocks INP as of Chrome 127! 🎉');
});

Still repros:

{
    "name": "script",
    "entryType": "script",
    "startTime": 13446.699999988079,
    "duration": 3763,
    "navigationId": "e754322a-fc20-4220-80f0-dfda1ffebbde",
    "invoker": "BUTTON#loafAlert.onclick",
    "invokerType": "event-listener",
    "windowAttribution": "self",
    "executionStart": 13446.699999988079,
    "forcedStyleAndLayoutDuration": 0,
    "pauseDuration": 0,
    "sourceURL": "https://inp-demo-dialog.glitch.me/",
    "sourceFunctionName": "",
    "sourceCharPosition": 37
}
mmocny commented 1 week ago

The demo page won't consistently report long INP now that the Event Timing duration was fixed for alerts. You can still make it long and get logged (via input delay) by interacting with the button while the page is blocked.

Alternatively, just open DevTools console and log all LoAFs with a script for event-listener:

new PerformanceObserver(list => list.getEntries()
  .flatMap(entry => entry.scripts)
  .filter(s => s.invokerType == "event-listener")
  .forEach(s => console.log(s)))
.observe({ type: 'long-animation-frame' });

(It still reproduces, fwiw)