React Native에서 FlatList 성능 개선 작업
문제 상황
이커머스 앱의 상품 목록 화면에서 스크롤 성능 이슈가 발생했다. 약 200개 정도의 상품 아이템을 렌더링하는데, 스크롤 시 프레임 드롭이 눈에 띄게 발생했다. 각 아이템은 이미지, 제목, 가격, 좋아요 버튼 등을 포함하고 있었다.
적용한 최적화
1. getItemLayout 구현
아이템 높이가 고정되어 있어서 getItemLayout을 구현했다.
getItemLayout={(data, index) => (
{length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
)}
2. removeClippedSubviews 활성화
화면 밖 뷰를 제거하는 옵션을 켰다. Android에서 특히 효과적이었다.
<FlatList
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={10}
/>
3. 이미지 최적화
react-native-fast-image 라이브러리로 교체했다. 캐싱과 우선순위 설정이 가능해 이미지 로딩이 훨씬 부드러워졌다.
import FastImage from 'react-native-fast-image';
<FastImage
source={{uri: item.imageUrl, priority: FastImage.priority.normal}}
style={styles.image}
resizeMode={FastImage.resizeMode.cover}
/>
4. keyExtractor 최적화
처음엔 index를 key로 사용했는데, 상품 ID를 사용하도록 변경했다.
keyExtractor={item => item.id.toString()}
결과
Perf Monitor로 확인했을 때 초당 프레임이 4045fps에서 5560fps로 개선되었다. 특히 Android 저사양 기기에서 체감 차이가 컸다. initialNumToRender를 줄이니 초기 렌더링 속도도 빨라졌다.
다음엔 React.memo와 useCallback을 활용한 리렌더링 최적화도 시도해볼 예정이다.