Skip to content

fix: Drop Android CSS transition animators when the React context goes - #10241

Merged
MatiPl01 merged 1 commit into
mainfrom
@matipl01/android-css-transition-teardown
Aug 13, 2026
Merged

MatiPl01 merged 1 commit into
mainfrom
@matipl01/android-css-transition-teardown

Conversation

@MatiPl01

Copy link
Copy Markdown
Contributor

The pre-draw listeners are registered on the window's ViewTreeObserver, which survives a React context teardown, so nothing removed them: after a reload they kept running every frame and retained the dead context through the manager.

NativeProxy.invalidate() now tears the manager down alongside pseudoSelectorManager, cancelling the animators, dropping the pending starts and removing the listeners. The reconciler keeps observer -> listener pairs so removal is possible at all; a HashSet of observers gave nothing to pass to removeOnPreDrawListener.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f765c285-de07-4166-89f6-e1bd273ceeb8

📥 Commits

Reviewing files that changed from the base of the PR and between ca4506b and 3cdb9b0.

📒 Files selected for processing (1)
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved cleanup of CSS-based transitions when views or animation systems are reset.
    • Prevented stale transition listeners from remaining attached after invalidation.
    • Ensured active transitions are cancelled and pending transitions are cleared during cleanup.
    • Improved reliability when views are recreated, detached, or otherwise become unavailable.

Walkthrough

CSS platform transition cleanup now tracks listener instances, rejects stale observers, blocks work after invalidation, cancels active animators, clears pending transitions, and runs from NativeProxy.invalidate().

Changes

CSS transition invalidation

Layer / File(s) Summary
Reconciler listener cleanup
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionReconciler.kt
The reconciler tracks listener identities, removes stale observers, retires listeners, and clears live listeners during invalidation.
Manager and native cleanup
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt, packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt
The manager blocks transition work after invalidation, clears pending starts, cancels active animators on the UI thread, and invalidates the reconciler. NativeProxy.invalidate() invokes this cleanup.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant NativeProxy
  participant CSSPlatformTransitionsManager
  participant ActiveAnimators
  participant CSSPlatformTransitionReconciler
  NativeProxy->>CSSPlatformTransitionsManager: invalidate()
  CSSPlatformTransitionsManager->>CSSPlatformTransitionsManager: mark invalidated and clear pending starts
  CSSPlatformTransitionsManager->>ActiveAnimators: cancel active animators on UI thread
  CSSPlatformTransitionsManager->>CSSPlatformTransitionReconciler: invalidate()
  CSSPlatformTransitionReconciler->>CSSPlatformTransitionReconciler: remove tracked pre-draw listeners
Loading

Possibly related PRs

Suggested reviewers: pawicao, tjzel

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the Android CSS transition animator teardown during React context teardown.
Description check ✅ Passed The description explains how the changes remove listeners, cancel animators, and prevent retention after React context teardown.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch @matipl01/android-css-transition-teardown

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-delay-playback branch from a874e64 to cb87314 Compare August 12, 2026 12:39
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-teardown branch from c5a0a61 to 1acacee Compare August 12, 2026 12:39
@MatiPl01 MatiPl01 self-assigned this Aug 12, 2026
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-delay-playback branch from cb87314 to 180e3db Compare August 12, 2026 12:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionReconciler.kt`:
- Around line 15-22: Update the tracking flow around track, invalidate, and
retire to resolve and retain the post-attachment window ViewTreeObserver as the
listener owner before pruning dead observers, ensuring listeners are removed
even when the temporary detached observer is invalidated. Preserve the
one-listener-per-window behavior and add a regression test covering detached
tracking, attachment, and invalidate().

In
`@packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt`:
- Around line 94-104: Make CSSPlatformTransitionsManager invalidation terminal
by adding a flag set before the UI-thread cleanup is posted. Guard
animateTransition() at entry and again inside its UI-thread lambda, returning
when invalidated so queued work cannot repopulate startTokens, create animators,
or call reconciler.track() after invalidate().
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1891504d-ceed-479e-ab50-7a768a274e65

📥 Commits

Reviewing files that changed from the base of the PR and between a874e64 and c5a0a61.

📒 Files selected for processing (3)
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.kt
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionReconciler.kt
  • packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/css/CSSPlatformTransitionsManager.kt

@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-teardown branch 2 times, most recently from c0dd12a to ca4506b Compare August 12, 2026 12:55
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-delay-playback branch from 180e3db to 4419a63 Compare August 12, 2026 13:03
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-teardown branch from ca4506b to 3cdb9b0 Compare August 12, 2026 13:19
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-delay-playback branch from 4419a63 to 1f30248 Compare August 12, 2026 13:29
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-teardown branch from 3cdb9b0 to 59515a8 Compare August 12, 2026 13:29
Base automatically changed from @matipl01/android-css-transition-delay-playback to main August 12, 2026 14:36
@MatiPl01
MatiPl01 force-pushed the @matipl01/android-css-transition-teardown branch from 59515a8 to 2a9450d Compare August 13, 2026 01:21
@MatiPl01
MatiPl01 requested a review from pawicao August 13, 2026 10:07
@MatiPl01
MatiPl01 merged commit 74324f2 into main Aug 13, 2026
11 checks passed
@MatiPl01
MatiPl01 deleted the @matipl01/android-css-transition-teardown branch August 13, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants