Commit 3ad1fcc
authored
Fix memory leak in ReanimatedSwipeable on programmatic close (#3790)
# Fix memory leak in ReanimatedSwipeable on programmatic close
## Problem
ReanimatedSwipeable experiences a performance leak when closing
programmatically via `.close()` or triggered by child content
interaction. The UI thread produces infinite updates even after the
spring animation visually finishes.
### Symptoms
- Infinite UI thread updates when calling `.close()` programmatically
- Animation appears complete but background processing continues
indefinitely
- Issue only occurs with programmatic closure, not manual swipe
gestures
- Affects iOS with react-native 0.81.0+ and gesture-handler 2.29.0
## Root Cause
The `animateRow` function accepts an optional `velocityX` parameter:
```typescript
const animateRow = (toValue: number, velocityX?: number) => {
```
When closing programmatically, no velocity value is provided,
resulting in velocityX = undefined.
The spring animation configuration requires numeric velocity values
to:
1. Calculate motion trajectory - how the value changes over time
2. Detect convergence - when animation should stop based on
restSpeedThreshold and restDisplacementThreshold
With undefined velocity:
- Spring cannot properly evaluate convergence conditions
- Animation loop never detects it should terminate
- UI thread continues updating indefinitely
Manual swipes work fine because gesture handlers provide actual
velocity values (e.g., -300, 150), ensuring valid numeric input.
Solution
Set a default parameter value for velocityX:
```typescript
const animateRow = (toValue: number, velocityX = 0) => {
```
This ensures:
- velocityX is always a number, never undefined
- Spring animation receives valid initial velocity of 0 (no momentum)
- Convergence detection works correctly - animation stops when
position settles
- Single point of fix at function signature level (cleaner than
multiple nullish coalescing checks)
Testing
- Programmatic .close() no longer causes infinite updates
- Manual swipe gestures continue to work correctly
- Animation behavior remains unchanged visually
Video from the same repo:
https://youtu.be/qqS_ZfSU7NI1 parent 7cfe2fc commit 3ad1fcc
1 file changed
Lines changed: 1 addition & 1 deletion
File tree
- packages/react-native-gesture-handler/src/components/ReanimatedSwipeable
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
206 | | - | |
| 206 | + | |
207 | 207 | | |
208 | 208 | | |
209 | 209 | | |
| |||
0 commit comments