motion icon indicating copy to clipboard operation
motion copied to clipboard

Track appear effect handover per element due to Suspense

Open kurtextrem opened this issue 1 year ago • 3 comments

Context

With nested Suspense boundaries, it might be that any children mount at a later timing than queueMicrotask guarantees. While we could switch to another timing-based method, it doesn't reliably ensure the call to completeHandoff happens after all children with optimized appear effects have mounted and run their mount useEffect. This means, if some child A mounted and has run an optimized appear effect, it would complete the handoff and make all further components (or children) falsely think they didn't have an optimized appear effect, which could lead to re-running of the appear effects on mount.

The fix

We now store the handover state per appear optimization element id, and only based on that state decide if we want to run further animations only from motion inside useEffect.

kurtextrem avatar Sep 23 '24 14:09 kurtextrem

This line checks if handoff is complete. If it is, we know that the animation is being interrupted by a subsequent animation, so we cancel the optimised animation and start the next animation from now. This is the source of the observed bug.

So if different components are handing off at different times, rather than keep the completion status of all components globally we would want to keep a boolean for each individual component.

mattgperry avatar Sep 24 '24 07:09 mattgperry

Hmm, so the handoff completed check is more like a "optimized appear animation started or running" check?

kurtextrem avatar Sep 24 '24 07:09 kurtextrem

Updated:

  • added a test (fails on master as expected, doesn't fail on this branch)
  • we now track the handover state per element (updated description), this is cheap as the only meaningful change here is Set -> Map

kurtextrem avatar Sep 24 '24 12:09 kurtextrem