w3c/long-animation-frames

pauseDuration is 0 while synchronous dialogs are shown

Opened this issue ยท 5 comments

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
{
    "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)

loaf-pause-duration.mov

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)

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

<button onclick="alert('This no longer blocks INP as of Chrome 127! ๐ŸŽ‰')">
  Alert
</button>

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

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
}

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)