-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Description
Description
React Native FPS Shows 60fps But UI Interactions Still Block - Why?
The Scenario:
I'm processing 4,500+ records in React Native and seeing confusing behaviour between two approaches:
Approach 1: Redux Dispatch (Large Payload)
javascript// 10MB JSON data dispatch to Redux
store.dispatch(setData(largePayload)); // Takes 6.7 seconds
FPS Counter: Drops to 0fps during dispatch
UI Animations: Completely frozen (useNativeDriver: false)
User Interactions: Blocked during dispatch, work after completion
Approach 2: Database Operations (Realm/WatermelonDB)
JavaScript// Bulk insert 4,500 records
realm.write(() => {
taskData.forEach(task => realm.create('Task', task)); // Takes 29-60 seconds
});
FPS Counter: Maintains 60fps throughout operation
UI Animations: Still completely frozen (useNativeDriver: false)
User Interactions: Blocked during operation, work after completion
The Mystery:
Why does the database approach show 60fps but animations and interactions behave identically to the 0fps Redux case? Both scenarios result in:
Frozen JavaScript animations
Blocked touch interactions during processing
Same functional outcome when operations complete
javascript// Animation test (useNativeDriver: false to test JS thread)
const animation = Animated.loop(
Animated.timing(value, {
toValue: 1,
duration: 2000,
useNativeDriver: false // Testing JS thread blocking
})
);```
Questions:
What does the FPS counter actually measure vs what affects animations/interactions?
Why do database operations maintain 60fps but still block JavaScript-based operations?
Is there a difference between "rendering performance" and "interaction responsiveness"?
Are there multiple threads involved that explain this discrepancy?
My Theory:
The FPS counter measures native UI thread rendering, while interactions depend on JavaScript thread availability. Database operations keep native rendering alive (60fps) but still saturate JavaScript thread preparation work.
Is this understanding correct? What's the architectural explanation for profiller showing 60fps with blocked interactions?
### Steps to reproduce
.
### React Native Version
0.76.0
### Output of `npx @react-native-community/cli info`
```text
System:
OS: macOS 14.5
CPU: (8) arm64 Apple M1
Memory: 87.56 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 20.19.4
path: ~/.nvm/versions/node/v20.19.4/bin/node
Yarn:
version: 1.22.1
path: ~/.nvm/versions/node/v20.19.4/bin/yarn
npm:
version: 10.8.2
path: ~/.nvm/versions/node/v20.19.4/bin/npm
Watchman:
version: 2025.09.01.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK: Not Found
Android SDK: Not Found
IDEs:
Android Studio: 2024.3 AI-243.24978.46.2431.13208083
Xcode:
version: /undefined
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.16
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 15.0.1
wanted: 15.0.1
react:
installed: 18.3.1
wanted: 18.3.1
react-native:
installed: 0.79.6
wanted: 0.79.6
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: false
newArchEnabled: false
Screenshots and Videos
No response