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

Element flashes before animation starts running. #3

Closed
minht11 opened this issue Apr 17, 2021 · 2 comments
Closed

Element flashes before animation starts running. #3

minht11 opened this issue Apr 17, 2021 · 2 comments

Comments

@minht11
Copy link

minht11 commented Apr 17, 2021

Before animation runs, content appears unstyled for a brief moment.

const onEnter = (element: Element, done: () => void) => {
   // At this point element shouldn't be visible but it is.
   element.animate({
      opacity: [0, 1],
    }, {
      duration: 100,
    }).finished.then(done)
}

Reproducible example some other person made:
https://codesandbox.io/s/cool-bogdan-j8b37?file=/package.json

One possible fix is to use 'onBeforeEnter' event but that only complicates things, especially with complex animations.
An actual fix would be to replace all 'setTimeout' uses with 'queueMicrotask', for example here:
https://github.com/ryansolid/solid-transition-group/blob/0f1d5253531246e51ea549adf8a002c7020ec5ad/src/Transition.ts#L63-L71
I have briefly tested it working locally with both native function and polyfill https://github.com/feross/queue-microtask

@ryansolid
Copy link
Collaborator

I see. I was trying to mimic the behavior of Vue Transition Group which seems to use setTimeout. I can see how this approach would be bulkier but honestly, I don't know all the use cases here so I've mostly been imitating. So for me to reconsider this I'd need to tread carefully. I am obviously interested where people have more experience and can explain why this behavior exists or when it is desirable. I am definitely interested in making this better but also not particularly versed in what that better looks like.

The way I see it the best path forward will be looking at the equivalent React and Vue examples and code to make some determinations. I might be missing some nuance here.

@minht11
Copy link
Author

minht11 commented Apr 20, 2021

I have tried to implement the same thing in react(no experience with Vue sorry) and it doesn't have same issues.
React example: https://codesandbox.io/s/naughty-lichterman-lsmqs?file=/src/App.js
Solid example: https://codesandbox.io/s/patient-wood-6vu4e?file=/index.js

The difference in timing could be attributed to the way solid renders and schedules DOM, but that's just speculation on my part. Reading up on queueMicrotask in MDN, it guaranties for code to run in specific order, before any other tasks are scheduled, just like Mutation Observer callback would. Inside previous standard discussion about it I also found this quote

setTimeout and rAF can cause UI flicker (rendering partially rendered UI)

which is exactly what is happening here, I am still not quite sure exactly how scheduling works, but it did fix animation flickering for me, but looking into more complex and varied use cases is the right decision before changing things up, there might be other unexpected things that come up.

Also issue seems to happen far less in Firefox, with simple animations it works normally 80% of the time, the more complex animation the more often it flickers. In Chromium flickering happens every time, I haven't tested Safari.

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

No branches or pull requests

2 participants