Skip to content
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

Svelte 5: WAAPI transitions can be hijacked in many ways, breaking the lifecycle of components #11273

Closed
Xerios opened this issue Apr 21, 2024 · 6 comments

Comments

@Xerios
Copy link

Xerios commented Apr 21, 2024

Describe the bug

After looking through #11270 I've done some research and realized that WAAPI may not be the best solution for transitions, at least not yet.

The fact that transitions now rely on the finish event of the animation no longer guarantees that the animation will finish after specified duration and allows external libraries break its intended behavior (see example). Even start isn't guaranteed to start on next frame).

For something as fundamental as transitions which can prevent destruction of an element, relying on a browser feature meant for trivial visual effects may have been simply a bad move.

Issues

  • events aren't reliable
    • start event isn't guaranteed to start on next frame (requires animation to be "ready" first)
    • they can be manipulated by external code and libraries (e.g. paused, canceled, slowed-down, timeline hijack) preventing the finish event call
  • duration/timing isn't absolute. I don't know for sure, but could it be that browser may pause all animations when the page is hidden?
  • hard to debug (afaik devtools has no way of showing that an animation is taking place, preventing the ability to apply styles)
  • there seems to be quite few pitfalls in regards to older browsers
  • perhaps future browser extensions may completely disable WAAPI (much like extensions that disable all animations by forcing css styles) which would prevent the events from firing at all

Proposed solution(s)

  • Instead of relying on delay, we handle the initial delay ourselves. This avoids the usage fill: 'both' which would activate the transition directly and lock the affected styles until the animation is finished or canceled. I assume we would need to apply the initial and final styles as well.
  • Same for transition end to ensure that the transition ends after specified duration and the element is destroyed. This may give some weird inconsistency if animation timing is different from other timings like setTimeout or RaF.
  • Reverting back to the old days, CSS animations which were easy to debug and worked nicely so far. I can't speak for everyone but I don't remember ever having any performance issues or bugs. Making WAAPI version optional behind a <svelte:options/> flag until new implementation is stable would be nice.
  • Wait for better APIs instead of fixing something that wasn't broken ( at least for me personally ):
    • A portion of transition use-cases (if not all) are already handled by the now released View Transitions API ( example: #1, #2 ). Available on Chrome, Firefox will follow, Webkit also supports the proposal.
    • Web Animation API 2 may come out by the time Svelte 5 is stable. I have not explored as it is still a draft document, but who knows maybe it will solve some of the current challenges.
  • Last but not least: Allow custom transitions. Svelte has been extremely customizable so far, but for years I have dreamt that one day we could have custom transitions where I could have full control over when and how transitions happen without relying on the hardcoded duration, delays, update rate, etc... Anyhow, this may be outside of the scope of this issue, but I just wanted to put my little rant here.

Reproduction

https://svelte-5-preview.vercel.app/#H4sIAAAAAAAACo1VYW_bNhD9KzcWgyRAsWQb_aJKHrzUw7y5dlC7G4KqH2jqFHOhSUGkmgiC_vtASXbipsv6wZD49O747vGObkjOBWoSfW6IpEckEZkXBfGJqQu70F9RGCQ-0aoqmUVizUpemFkqU8OPhSoNNJDTDH3IRe2DZlQgtJCX6ghOHx-YkkrNDVfSeWcDBRrQB_UACeRUaDyD91wIzC5g-2NKagOGH1FwiZCAxAf4i-PDboDcxtIAdLX_B5mJIFOsOqI0o9PLQqB9-D2PPnIdQUr2QrH7lAwolxpNBJ-vt9tR8eimZBKGKfF8OAPTDvjS8Vuv19cpzCvJbH1dBa7X9F80GqtQVcZ1vWQ2oKk5q9urrB7doZlLfqQ2XruNLcKUiBGYskJovVGuygVlB9elJ5oHyQzO6U4GoVha786sEeY5MjMytLxDM-IZBAEINBpoUYgaMp7nWKI0wKhGDUYBUnYA7L16Ss9zcG3yJEmJNSA1T3sUtNLoek9kFBrhecQ4Jd4zUYxKhuLViMllRFVk1OCNoPWesvuP1KAbjsavJZheJnjWOafXU3A7pIGh9xJreg-1PkzDsPvenhrU5kwcngl0UhkH52GI95UxSoKSTHB2nzT2vPsTGhr9J_u062GfrsNPa-tG284ay_nFOfAMncixC6eNgz61nTgZHyazxmpo4-Aw6aDmDc-7Yeo0xocx8Kw_JmCCah0NM_U0g1Eu6qRpIKvKzp4IxmEY-vAYgXM1Dn922haU5NKUShtamr6YoXKLXnWw08KJhjJ7SUKZ9RRVfS9Th54zDaxvEvWcLtFs93G-3i53y80a3Jv5p-3Ci4PDeJbKJuB5-58-jL_1QVUmsvdV0jQZClpH8NYWf2lG287eL1bz28V72HzawWa9ugX3er6-Xqx-bNvJ_9o_bD55ubkPqqCMmzoa-1BH4IzD7lCeW7Bdbf7-sAH3ZjW__XV-_eePqZq-oqq7uL_XFt0RRRO4EBDvy2Dm7pYfFqvlegG_L_94KSLO-FfQphaYpKSgWcbl3dVeGaOO0duwxGNKgr6rO1L3lzIahA13G1NClRG8-W06fTfMYRyc2MQnR5XxnGNGIju27Zf2X0W26zzRBgAA

Logs

No response

System Info

All browsers

Severity

annoyance

@Rich-Harris Rich-Harris added this to the 5.0 milestone Apr 21, 2024
@Xerios
Copy link
Author

Xerios commented Apr 26, 2024

There's also @starting-style which is a pure CSS solution for dealing with in/out transitions. Available for Chromium browsers and Safari 17.5 TP.

Note that inside their examples, they also make use of setTimeout to remove the element after duration.

@Azarattum
Copy link
Contributor

I'd say that allowing to hijack animations is a good thing. This way library authors could actually implement custom transitions without relying on inconsistent timings. And if they mess something up, it's their responsibility that should not be shifted to the framework. A dedicated custom transition API would obviously be better, but even if we won't get one, the escape hatch is better than noting at all. I personally had a lot of pain dealing with custom non-deterministic transitions in Svelte 4. I hope with v5 it would finally be not only possible but pleasant.

@Xerios
Copy link
Author

Xerios commented Jul 10, 2024

I don't disagree about the ability to hijack. However, visual animations and UI states are two different realms. If an element doesn't get destroyed when it's supposed to get destroyed, this would only lead to unexpected issues.

There should be some mechanism like setTimeout that forcefully destroys the element without relying on WAAPI.

@trueadm
Copy link
Contributor

trueadm commented Aug 22, 2024

We're not planning on changing direction with this for Svelte 5. Whilst WAAPI might have some gotchas, we've largely been able to work around the existing bugs and what we have today is largely equivalent to Svelte 4. We've also noticed that stability in some browsers has improved in the last few months already too – and some oddities are no longer present. For these reasons, we don't feel like the change in direction and the impact it will have on Svelte 5 is worth it.

@trueadm trueadm closed this as not planned Won't fix, can't repro, duplicate, stale Aug 22, 2024
@Azarattum
Copy link
Contributor

some browsers has improved in the last few months

What about browsers that don't auto-update like Safari on iOS? Is everything stable there and what would be the minimum supported iOS version then?

@Xerios
Copy link
Author

Xerios commented Aug 26, 2024

As long as you guys are aware of the current issues, it's all good to me. Hopefully some of my research has come in handy.

I think the ability to customize the compiler animation handling (e.g. make it use some 3rd party library, or custom code) would've been the most satisfying outcome (at least for me personally).

As the person above stated, it's unfortunate that support for older browsers (anything before 2021) and systems that can't upgrade while being stuck with older browser versions (older iOS, kiosks and gov-regulated OS's) would be dropped and won't be able to use Svelte 5 out-of-the-box.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants