
문제현상
이미지 아이템이 많으면 스크롤 시 버벅거림이 심해져 사용자 경험에 좋지 않은 영향을 주고 있으므로 수정이 필요했다
컴포넌트 구조
* 페이지 : MainShop, BrandShop, ProductSearchResult -> 여기서 각각 ScrollView를 사용하고 있다
* 컴포넌트 ProductList (FlatList 사용) -> 각 페이지의 ScrollView 안에 ProcudtList를 사용하고 있다
수정방법 1. 무한스크롤
너무 많은 이미지를 한번에 보여주고 있어서 30개씩 아이템을 보여주는 무한스크롤을 사용했다. ScrollView의 onScroll 함수를 사용하여 화면의 끝에 닿을 경우 보여주는 아이템 개수(renderCount, renderList)를 수정하는 방식이었다.
// ScrollView의 onScroll 수행시 작동되는 함수 - 스크롤 위치를 계산하여 콜백함수가 수행되도록
const ScrollDownCallback = ({
event,
callback,
bottomRef,
}: {
event: NativeSyntheticEvent<NativeScrollEvent>;
callback: () => void;
bottomRef: React.RefObject<boolean>;
}) => {
const { nativeEvent } = event;
const { layoutMeasurement, contentOffset, contentSize } = nativeEvent;
const isCloseToBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height - 20;
// 바닥에 닿았는지 확인 = 화면높이 + 스크롤 위치 >= 전체 높이 - 20
if (isCloseToBottom && !bottomRef.current) {
bottomRef.current = true;
callback();
} else if (bottomRef.current) {
bottomRef.current = false;
}
};
// 콜백함수에는 스크롤된 횟수(renderCount)와 아이템 리스트(renderList) 상태가 변경됨
<ScrollView
onScroll={e =>
handleScroll({
event: e,
callback: () => {
setRenderList(productList.slice(0, renderCount * 30));
setRenderCount(prev => prev + 1);
},
bottomRef,
})
}
>
➡️ 문제점 : 이렇게 할 경우 5번째 스크롤까지는 끊김없이 잘 보이지만 이후에는 렌더링되는 양이 많아져 스크롤을 내리면 똑같이 버벅거림
수정방법 2. ScrollView, FlatList 중첩 삭제
기본적으로 이 둘을 중첩해서 사용하는걸 지양해야한다
* 중복 스크롤 영역 문제 : FlatList는 내부적으로 ScrollView 기반이다. 그래서 ScrollView 안에 FlatList를 넣으면 부모 ScrollView와 자식 FlatList가 각각 스크롤 이벤트를 관리하게 된다.
* 성능저하 : FlatList의 장점은 가상화(virtualization : 보이는 아이템만 렌더링하고, 보이지 않는 아이템은 언마운트해서 성능 최적화) 기능이다. 그런데 ScrollView 안에 넣으면 모든 아이템을 한번에 렌더링해서 FlatList의 가상화 효과가 사라진다.
그래서 각 페이지의 ScrollView를 삭제하고 FlatList를 넣어주는데, item 컴포넌트를 따로 만들어 renderItem에 넣어주었다. 이 과정에서 ProductList는 삭제됐다. onEndReached를 사용하면 무한렌더링을 구현할 수 있지만 중첩을 삭제하는 것만으로도 스크롤 버벅거림이 없어졌기 때문에 따로 구현할 필요는 없었다.
수정방법3. react-native-fast-image 라이브러리 사용
이 방법은 방법2를 사용하고도 버벅거림이 발생할 때 사용하는 방법이다.
많은양의 이미지가 있는 경우 한꺼번에 이미지 디코딩이 일어나기 때문에 Bridge(js와 네이티브간의 통신) 병목현상으로 인한 스크롤 끊김 현상이 발생할 수 있다. 이때 네이티브 단에서 이미지 디코딩을 해주는 react-native-fast-image 라이브러리를 사용하면 js 스레드가 가벼워져 버벅거림이 줄어든다.
다시 한번 더 탄탄한 기본기를 갖춰야 작은 버그들이 생기지 않는다는 것을 깨닫게되었다.
'React-Native' 카테고리의 다른 글
| [리액트 네이티브] Tab Navigator에서 params에 따라 렌더링하기 (0) | 2025.12.03 |
|---|---|
| [리액트 네이티브] 무한렌더링으로 아이템 정렬하면서 스크롤 시 탭 상단에 고정시키기 (ScrollView의 stickyHeaderIndices, useInfiniteQuery) (0) | 2025.11.29 |
| [에러해결] 푸시 알람으로 페이지 진입 후 댓글 작성 시 반영안됨 (queryClient.invalidateQueries 사용) (2) | 2025.08.25 |
| npm run ios 에러 해결기 2 (7) | 2025.08.13 |
| 리액트 네이티브 모듈 sdk 붙이기 (안드로이드 스튜디오) - adiscope (7) | 2025.05.18 |