Bug 299823

Summary: REGRESSION(294049@main): starting an animation via el.animate().reverse only works every other time
Product: WebKit Reporter: Caleb Hearon <caleb>
Component: AnimationsAssignee: Antoine Quint <graouts>
Status: RESOLVED FIXED    
Severity: Normal CC: graouts, graouts, karlcow, stephen, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 26   
Hardware: Mac (Intel)   
OS: macOS 26   
See Also: https://bugs.webkit.org/show_bug.cgi?id=290993

Caleb Hearon
Reported 2025-09-29 14:10:33 PDT
jsfiddle: https://jsfiddle.net/n962tryh/ - Safari 18 animates the div every button click - Safari 26 animates the 1st, 3rd, 5th... times - Firefox animates every click - Chrome animates every click I don't know Web Animations well enough to know what should happen, or if this is an under-specified area, but it broke our app. It's possibly Intel-specific: my colleague was not able to reproduce on Apple Silicon
Attachments
Stephen Thomas
Comment 1 2025-09-29 15:36:50 PDT
Can confirm with Safari 26.0.1 on Sequoia as well. Versions 15.7 and 15.7.1. But only on a Mini with an Intel CPU. No bug observed on a different M4 Mini.
Radar WebKit Bug Importer
Comment 2 2025-10-06 14:11:10 PDT
Antoine Quint
Comment 3 2025-10-06 23:37:11 PDT
It's not Intel-specific, I can reproduce this with Safari 26.0.1 on macOS Tahoe 26.0.1 (25A362). Will find the regression point.
Antoine Quint
Comment 4 2025-10-06 23:42:12 PDT
It appears to already have been broken in 294709@main.
Antoine Quint
Comment 5 2025-10-07 07:26:50 PDT
The regression range is https://commits.webkit.org/compare/294072@main...294026@main. This most likely this regressed with 294049@main, the fix for bug 290993.
Antoine Quint
Comment 6 2025-10-12 01:03:27 PDT
Oddly enough this does not reproduce with the HTML and JS code pasted into an HTML file. But it does within the iframe on jsfiddle.
Antoine Quint
Comment 7 2025-10-12 05:39:25 PDT
I expect this is going to be something to do with throttling.
Antoine Quint
Comment 8 2025-10-12 06:05:13 PDT
There's really something specific to jsfiddle here. If I call `document.getAnimations()[0].cancel()` after the page is loaded, the bug stops reproducing.
Antoine Quint
Comment 9 2025-10-12 06:08:08 PDT
So there's some bad interaction between the CSS Animation applied to the "AN" avatar in the page's top bar above the HTML and the animation in the content. Will try to reduce this, but it's quite odd.
Antoine Quint
Comment 10 2025-10-12 13:12:20 PDT
This can be reduced to a host document running a constant background-color animation while a child document, hosted via an <iframe>, animates using the reverse() method.
Antoine Quint
Comment 11 2025-10-13 00:10:51 PDT
I think this is due to timers being throttled in iframes and the call to `AnimationTimelinesController::processPendingAnimations()` taking longer than expected to run, only after the next animation resolution, and thus the animation never getting a committed start time.
Stephen Thomas
Comment 12 2025-10-13 03:15:01 PDT
Just a note to add that we encountered the bug in our application, which does not use Iframes. So it is NOT strictly an iframe issue
Antoine Quint
Comment 13 2025-10-13 03:32:46 PDT
So far I've only managed to reproduce the issue in the context of iframes where timing is different… but since this is a timing issue, I expect this may occur depending on the JavaScript performance. If you can make a reduction that does not involve iframes, it would be good to see it as well.
Antoine Quint
Comment 14 2025-10-13 03:53:25 PDT
Stephen Thomas
Comment 15 2025-10-13 04:24:52 PDT
Looks like the issue has been found, but for completeness, unfortunately our application code is too complex to share easily (and is also proprietary) but the fact that we could easily reproduce on Intel clients but not Apple Silicon clients definitely supports the idea that it's timing/performance related. I can share the workaround we deployed, if that's helpful. Broken: ``` const animation = el.animate(keyframes, {duration: 200}); animation.addEventListener("finish", done); if (reverse) animation.reverse(); ``` Works: ``` if (reverse) keyframes.reverse(); const animation = el.animate(keyframes, {duration: 200}); animation.addEventListener("finish", done); ```
EWS
Comment 16 2025-10-13 09:25:23 PDT
Committed 301414@main (841997317f49): <https://commits.webkit.org/301414@main> Reviewed commits have been landed. Closing PR #52233 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.