React Native에서 FlatList 성능 개선 경험
문제 상황
소셜 피드 기능을 개발하면서 FlatList에 100개 이상의 아이템을 렌더링할 때 스크롤 성능이 급격히 저하되는 문제를 겪었다. 특히 안드로이드 중저사양 기기에서 프레임 드롭이 심각했다.
원인 분석
프로파일러를 돌려보니 두 가지 문제가 있었다.
- 모든 아이템이 매 스크롤마다 재렌더링
- 아이템 높이 계산을 위한 레이아웃 측정 오버헤드
해결 방법
1. React.memo로 불필요한 렌더링 방지
const FeedItem = React.memo(({ item }) => {
return (
<View style={styles.item}>
<Text>{item.title}</Text>
<Image source={{ uri: item.thumbnail }} />
</View>
);
}, (prevProps, nextProps) => {
return prevProps.item.id === nextProps.item.id;
});
2. getItemLayout으로 높이 사전 계산
아이템 높이가 고정되어 있어서 getItemLayout을 사용했다.
<FlatList
data={feeds}
renderItem={renderItem}
keyExtractor={item => item.id}
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={10}
/>
3. 추가 최적화 옵션
removeClippedSubviews: 화면 밖 뷰 언마운트maxToRenderPerBatch: 한 번에 렌더링할 아이템 수 제한windowSize: 현재 화면 기준 렌더링 범위 설정
결과
- 스크롤 FPS: 30
40 → 5560 - 초기 로딩 시간: 2.1초 → 1.3초
고정 높이가 아닌 경우는 onLayout으로 측정한 높이를 캐싱하는 방식도 고려해볼 만하다.