AnimatedFlatList's scroll and drag performance - Reanimated2
See original GitHub issueDescription
AnimatedFlatList’s scroll and drag performance seems poor. I’m just using opacity and scale property for animation with interpolation. During scroll performance was not good but if I was dragging slowly, ui thread performance was descending so dramatically. Did I miss something? My test device is iPhone6s
Screenshots
Steps To Reproduce
See code below. You can copy and paste to any project, it will work.
Expected behavior
Smooth 60fps opacity and scale animation.
Actual behavior
2-30 fps animation 😦
Snack or minimal code example
import React from 'react';
import {StyleSheet, FlatList, View, Text, Dimensions} from 'react-native';
import Animated, {
Extrapolate,
interpolate,
useAnimatedScrollHandler,
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated';
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
const items = [
{id: 1, text: 'A'},
{id: 2, text: 'B'},
{id: 3, text: 'C'},
{id: 4, text: 'D'},
{id: 5, text: 'E'},
{id: 6, text: 'F'},
{id: 7, text: 'G'},
{id: 8, text: 'H'},
{id: 9, text: 'I'},
{id: 10, text: 'J'},
{id: 11, text: 'K'},
{id: 12, text: 'L'},
];
const {width: SCREEN_WIDTH} = Dimensions.get('window');
const ITEM_WIDTH = SCREEN_WIDTH / 5;
const data = [...items, ...items, ...items];
export const Home = () => {
const transX = useSharedValue(0);
const renderItem = ({item, index}) => {
return <Item index={index} item={item} transX={transX} />;
};
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
transX.value = event.contentOffset.x;
},
});
return (
<View style={styles.container}>
<View style={styles.listContainer}>
<AnimatedFlatList
onScroll={scrollHandler}
horizontal
showsHorizontalScrollIndicator={false}
style={styles.list}
data={data}
decelerationRate="fast"
centerContent
snapToInterval={ITEM_WIDTH}
scrollEventThrottle={16}
pagingEnabled
snapToAlignment="center"
renderItem={renderItem}
keyExtractor={(item, index) => `${item.id}-${index}`}
/>
</View>
</View>
);
};
const Item = ({index, item, transX}) => {
const animatedStyle = useAnimatedStyle(() => {
return {
opacity: opacityAnimation(transX, index),
transform: [
{
scale: scaleAnimation(transX, index),
},
],
};
});
return (
<Animated.View style={[styles.box, animatedStyle]} item={item}>
<Text style={styles.label}>{item.text}</Text>
</Animated.View>
);
};
const scaleAnimation = (transX, index) => {
'worklet';
return interpolate(
transX.value,
[
(index - 2) * ITEM_WIDTH,
(index - 1) * ITEM_WIDTH,
index * ITEM_WIDTH,
(index + 1) * ITEM_WIDTH,
(index + 2) * ITEM_WIDTH,
],
[0.5, 0.7, 1, 0.7, 0.5],
Extrapolate.CLAMP,
);
};
const opacityAnimation = (transX, index) => {
'worklet';
return interpolate(
transX.value,
[
(index - 3) * ITEM_WIDTH,
(index - 2) * ITEM_WIDTH,
(index - 1) * ITEM_WIDTH,
index * ITEM_WIDTH,
(index + 1) * ITEM_WIDTH,
(index + 2) * ITEM_WIDTH,
(index + 3) * ITEM_WIDTH,
],
[0, 0.5, 0.8, 1, 0.8, 0.5, 0],
Extrapolate.CLAMP,
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#efefef',
},
listContainer: {
height: ITEM_WIDTH + 250,
alignItems: 'center',
justifyContent: 'center',
},
list: {
height: ITEM_WIDTH * 2,
flexGrow: 0,
paddingHorizontal: ITEM_WIDTH * 2,
},
box: {
width: ITEM_WIDTH,
height: ITEM_WIDTH,
backgroundColor: 'blue',
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.37,
shadowRadius: 7.49,
elevation: 12,
},
label: {
fontWeight: 'bold',
fontSize: 24,
color: '#fff',
},
});
Package versions
- React: 16.13.1
- React Native: 0.63.3
- React Native Reanimated: 2.0.0-rc.0
- NodeJS: 14.4.0
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:18 (4 by maintainers)
Top Results From Across the Web
useAnimatedScrollHandler | React Native Reanimated
This is a convenience hook that returns an event handler reference which can be used with React Native's scrollable components.
Read more >Animations - React Native
React Native provides two complementary animation systems: Animated ... ScrollView , FlatList and SectionList , but you can also create your ...
Read more >react-native-draggable-flatlist - npm
React Native Draggable FlatList. A drag-and-drop-enabled FlatList component for React Native. Fully native interactions powered by Reanimated ...
Read more >Unanswered 'react-native-reanimated-v2' Questions - Page 2
React Native Gesture Handler + Reanimated Flat List Scroll. I'm having a problem with react-native-gesture handler animation in a FlatList. when i try...
Read more >Scrollable Bottom Sheet with virtualisation, native animations ...
You can scroll the list to the top and drag the bottom sheet down on the ... Inifinite scrolling onboarding animation made with...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Video:
I also added getItemLayout to FlatList with useCallbacks, animation increased to 60 fps 🥳 🥳 🥳