Skip to content

[Fabric LA] Fix maybeDropAncestors condition. #6663

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

Merged
merged 5 commits into from
Jan 8, 2025

Conversation

bartlomiejbloniarz
Copy link
Contributor

@bartlomiejbloniarz bartlomiejbloniarz commented Nov 4, 2024

Summary

In the maybeDropAncestors function we can remove the view if it has no remaining animating views. Let's say we have nested exiting animations:

flowchart TD
    A((A: EXITING))
    B((B: EXITING))
    C((C: WAITING))
    D((D: WAITING))
    E((E: WAITING))

    A --> B
    A --> C
    A --> D
    A --> E

Loading

In the current implementation in this case if the animation in B ended before A, we would visit A in maybeDropAncestors and decided to remove A, even though it still has some waiting children. Then A would be added to the view recycling pool while still having children. This would cause us to see some zombie views when the view is reused.

I changed the maybeDropAncestors condition to check the size of the children list. I also removed node->animatedChildren as I think it is no longer necessary.

Fixes #6644

Test plan

Chceck [LA] View recycling example, if there are no zombie views in the WheelPicker component.

@bartlomiejbloniarz bartlomiejbloniarz changed the title @bartlomiejbloniarz/fix drop ancestors [Fabric LA] Fix maybeDropAncestors condition. Nov 4, 2024
Copy link
Member

@piaskowyk piaskowyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smart 👍
Just to be sure if I understand correctly - We can simply rely on checking the count of children since they are detached before the parent, correct?

@bartlomiejbloniarz
Copy link
Contributor Author

@piaskowyk We maintain the children count by observing mutations. We can remove the node only if there are no children left, as that means that all animations in the subtree have finished. The previous version was using the animatedChildren set, which actually didn't take all children into account, leading to us sometimes removing a node before its children.

@bartlomiejbloniarz bartlomiejbloniarz added this pull request to the merge queue Jan 8, 2025
Merged via the queue into main with commit a2cdebd Jan 8, 2025
17 checks passed
@bartlomiejbloniarz bartlomiejbloniarz deleted the @bartlomiejbloniarz/fix-drop-ancestors branch January 8, 2025 13:55
tjzel pushed a commit that referenced this pull request Feb 17, 2025
## Summary

In the `maybeDropAncestors` function we can remove the view if it has no
remaining animating views. Let's say we have nested exiting animations:

 ```mermaid
 flowchart TD
     A((A: EXITING))
     B((B: EXITING))
     C((C: WAITING))
     D((D: WAITING))
     E((E: WAITING))
 
     A --> B
     A --> C
     A --> D
     A --> E
 
 ```
In the current implementation in this case if the animation in `B` ended
before `A`, we would visit `A` in `maybeDropAncestors` and decided to
remove `A`, even though it still has some waiting children. Then `A`
would be added to the view recycling pool while still having children.
This would cause us to see some zombie views when the view is reused.
 
I changed the `maybeDropAncestors` condition to check the size of the
`children` list. I also removed `node->animatedChildren` as I think it
is no longer necessary.

Fixes #6644 

## Test plan
Chceck `[LA] View recycling` example, if there are no zombie views in
the `WheelPicker` component.
tjzel pushed a commit that referenced this pull request Feb 17, 2025
## Summary

In the `maybeDropAncestors` function we can remove the view if it has no
remaining animating views. Let's say we have nested exiting animations:

 ```mermaid
 flowchart TD
     A((A: EXITING))
     B((B: EXITING))
     C((C: WAITING))
     D((D: WAITING))
     E((E: WAITING))
 
     A --> B
     A --> C
     A --> D
     A --> E
 
 ```
In the current implementation in this case if the animation in `B` ended
before `A`, we would visit `A` in `maybeDropAncestors` and decided to
remove `A`, even though it still has some waiting children. Then `A`
would be added to the view recycling pool while still having children.
This would cause us to see some zombie views when the view is reused.
 
I changed the `maybeDropAncestors` condition to check the size of the
`children` list. I also removed `node->animatedChildren` as I think it
is no longer necessary.

Fixes #6644 

## Test plan
Chceck `[LA] View recycling` example, if there are no zombie views in
the `WheelPicker` component.
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

Successfully merging this pull request may close these issues.

React Native 0.76: Previous Item Remains Visible on State-Driven Navigation
2 participants