🚨 문제점: 과도한 데이터 소모 & 깜빡임 현상 발생
초기 방식: 모든 동영상을 한 번에 불러옴
초기에는 FlatList를 사용해 한 페이지당 **3개의 답지 인덱스(최대 45개 영상)**를 불러오도록 구현했다.
하지만 모든 동영상이 동시에 요청되고 자동 재생되어, 데이터 사용량이 급격히 증가했다.
📌 문제점 정리
✔ 한 페이지당 최대 2.5GB 데이터 사용
✔ 화면에 보이지 않는 동영상도 미리 로드됨
✔ 스크롤 시 깜빡임 발생 (썸네일 → 동영상 전환 시)
✅ 해결 목표:
- 보이는 동영상만 로드 & 재생하도록 최적화
- 불필요한 데이터 요청을 최소화
- 부드러운 전환을 위한 깜빡임 방지
🔍 해결 과정: 최적화 적용하기
1. onViewableItemsChanged 활용 - 보이는 영상만 재생
📌 기존 방식
- FlatList가 한 번에 모든 동영상을 렌더링
- 보이지 않는 동영상도 API 요청 & 자동 재생 → 데이터 낭비
📌 개선 방법
- onViewableItemsChanged를 사용해 뷰포트(현재 보이는 화면)에 있는 동영상만 재생
- setVisiblePostIndex()를 이용해 현재 인덱스만 업데이트
const onViewableItemsChanged = useRef(({ viewableItems }: any) => {
if (viewableItems.length > 0) {
const visibleIndex = viewableItems[0].index;
setVisiblePostIndex(visibleIndex);
}
}).current;
✅ 적용 후:
✔ 화면에 보이는 동영상만 API 요청
✔ 데이터 사용량 대폭 감소
✔ 불필요한 GPU/CPU 리소스 사용 줄어듦
2. Lazy Loading (지연 로딩) 적용 - 썸네일 먼저 로드 후 동영상 요청
📌 기존 방식
- media 배열에 포함된 모든 동영상 URL을 즉시 요청
- 초기 로딩 시 불필요한 네트워크 사용량 증가
📌 개선 방법
- 썸네일 이미지(thumbnailUrl)를 먼저 로드
- 동영상은 사용자가 실제로 보려고 할 때만 요청
const renderItem = ({ item, index }: { item: string; index: number }) => (
<View style={styles.videoBox}>
{isParentVisible && currentIndex === index ? (
<VideoItem uri={item} isPlaying={true} />
) : (
<Image
source={{ uri: "thumbnail_url" }} // 썸네일 URL 사용
style={{ width: SCREEN_WIDTH, height: 200 }}
/>
)}
</View>
);
✅ 적용 후:
✔ 썸네일만 표시 → 동영상이 필요할 때만 요청
✔ 네트워크 트래픽 감소 → 데이터 사용량 절감
✔ 렌더링 속도 개선 → 사용자 경험(UX) 향상
3. API 요청 방식 변경 - 개별 동영상 요청으로 최적화
📌 기존 방식
- 답지별로 한 번에 모든 동영상을 로드
- 사용자가 실제로 보지 않는 영상도 불필요하게 요청됨
📌 개선 방법
- media 배열을 제거하고 각 동영상을 개별 API 요청
- 사용자가 해당 동영상을 클릭하거나 스크롤할 때만 요청
const {
data: currentVideoUrl,
isLoading,
} = useQuery({
queryKey: ["singleVideoDatasKey", postId, currentIndex],
queryFn: () => fetchRenderSingleVideo(postId, currentIndex),
enabled: !!isParentVisible,
});
✅ 적용 후:
✔ API 요청 수는 증가하지만, 총 데이터 소모량은 획기적으로 감소
✔ 한 번에 모든 데이터를 불러오지 않고, 필요한 데이터만 가져옴

- 하지만 여기서 인덱스를 바꿀 때마다 데이터를 계속 요청하늠 문제 발생,
- 인덱스가 바뀔 때마다 쿼리 키가 달라지기 때문일것이라 생각,
4. React Query staleTime, gcTime 적용 - 캐시를 활용해 중복 요청 방지
📌 기존 문제
- 인덱스를 변경할 때마다 같은 데이터를 반복 요청
- 불필요한 API 호출 증가 → 성능 저하 & 데이터 낭비
📌 개선 방법
- staleTime을 설정해 캐시된 데이터를 일정 시간 유지
- 동일한 key로 요청해도, 백그라운드에서 재요청하지 않고 캐시 데이터를 사용
const {
data: currentVideoUrl,
} = useQuery({
queryKey: ["singleVideoDatasKey", postId, currentIndex],
queryFn: () => fetchRenderSingleVideo(postId, currentIndex),
enabled: !!isParentVisible,
staleTime: 1000 * 60 * 5, // 5분 동안 fresh 상태 유지
gcTime: 1000 * 60 * 10, // 10분 후 캐시 삭제
});
✅ 적용 후:
✔ 동일한 인덱스의 데이터를 반복 요청하지 않음
✔ 캐시 덕분에 빠른 로딩 & 성능 최적화

- fresh상태가 되어 인덱스를 넘겨도 데이터가 재요청 되지 않음, 일단은 성공적
5. 깜빡임 방지 - isVideoReady 상태 추가
📌 기존 문제
- 동영상이 로드될 때 썸네일에서 동영상으로 전환하는 순간 깜빡임 발생
- 썸네일과 동영상의 비율이 다를 경우 UI 불안정
📌 개선 방법
- isVideoReady 상태를 추가하여 동영상이 준비된 후에만 썸네일 제거
- onReadyForDisplay 이벤트를 활용하여 비디오 로드 완료 후 상태 업데이트
const handleVideoReady = (index: number) => {
setVideoReadyStates((prev) => ({
...prev,
[index]: true,
}));
};
const renderItem = ({ item, index }: { item: string; index: number }) => (
<View style={styles.videoBox}>
<VideoItem
uri={index === currentIndex ? currentVideoUrl : null}
isPlaying={!!isParentVisible && currentIndex === index}
isVideoReady={!!videoReadyStates[index]}
onVideoReady={() => handleVideoReady(index)}
thumbnailUri={item} // 썸네일 URL 전달
/>
</View>
);
✅ 적용 후:
✔ 썸네일이 사라지기 전에 동영상이 완전히 준비됨 → 깜빡임 방지
✔ 썸네일과 동영상의 크기를 동기화하여 UI 안정성 향상
'프로젝트 답지' 카테고리의 다른 글
업로드 상황에 따른 Progress 구현 (0) | 2025.02.10 |
---|---|
앱에서 앨범에 접근해 동영상 불러오는 시간 줄이는 방법 (0) | 2025.01.27 |
앱스토어 승인 리젝 사유 모음집 => 승인 통과된 결과 (1) | 2024.12.13 |
react-query의 데이터 깜빡임 해결 건(placeholderData) (0) | 2024.12.09 |
프로젝트 간단 정리 (2) | 2024.12.06 |