이 포스트의 일부 결론은 후속 테스트에서 재평가되었습니다. 업데이트된 정보는 여기를 참조해주세요.
1. 문제 상황
- 커뮤니티 리스트 페이지의 초기 로딩 시간이 너무 길어 사용자 경험 저하
- 팀원이 자신의 인터넷 연결 문제로 오해할 정도로 느린 로딩 속도
2. 분석 과정
- MVP 우선으로 작성된 코드 전체 리뷰
- 각 카테고리별 데이터를 UX 이유로 미리 불러오는데 동기로 불러오는 것을 발견
- 불필요한 리렌더링 발생 확인 (콘솔 로그 활용)
3. 최적화 전략 및 구현
3.1 데이터 페칭 최적화
최적화 전 코드:
const fetchCategoryData = async () => {
for (const category of categories) {
await queryClient.prefetchInfiniteQuery(queryOptions.posts(category));
}
};
최적화 후 코드:
const fetchCategoryData = async () => {
const prefetchedCategories = queryClient.getQueryData(['prefetchedCategories']);
if (!prefetchedCategories) {
await Promise.all(categories.map((cat) => queryClient.prefetchInfiniteQuery(queryOptions.posts(cat))));
queryClient.setQueryData(['prefetchedCategories'], true);
}
};
3.2 SSR과 CSR 결합
- 초기 데이터는 SSR로 props 전달
- 무한 스크롤은 클라이언트에서 처리
3.3 컴포넌트 최적화
- 커뮤니티 리스트 항목 메모이제이션
- 좋아요로 항목 값이 바뀌어서 메모제이션이 소용이 없는 것을 확인
- 좋아요 버튼 컴포넌트 분리 및 지역 상태 관리로 사용자에게 표시
최적화 후 코드:
const LikeButton = React.memo(({ post }) => {
const [isLiked, setIsLiked] = useState(post.isLiked);
const [likeCount, setLikeCount] = useState(post.likeCount);
// 좋아요 로직
// onSettled 제거
}
이 접근 방식을 선택한 이유:
- 이전에 낙관적 업데이트의 불필요한 리렌더링을 방지하기 위해 개발자(튜터)님 조언을 받고 적용했음
- 캐시 초기화를 하지 않아 불필요한 리렌더링 방지
- onError로 에러 처리를 통해 데이터 일관성 유지
- 컴포넌트 리마운트 시 서버 데이터와 동기화되므로 장기적 일관성 보장
4. 결과 및 개선사항
- 사용자 경험 크게 개선
- 불필요한 리렌더링 감소로 전반적인 성능 향상
- 주의: 이 비교는 다른 환경(Vercel vs 로컬)에서 수행되었으며, 이로 인해 결과가 왜곡되었을 수 있습니다. 자세한 내용은 후속 포스트를 참조하세요
5. 배운 점 및 향후 개선 방향
- SSR의 중요성 재인식: 로딩 상태보다 초기 콘텐츠 표시가 UX에 더 중요
- Suspense와 SSR 조합의 가능성 발견
- 개별 Promise 실패 시 전체 실패 문제 해결 필요
'TIL' 카테고리의 다른 글
HTTP/HTTPS와 REST/GraphQL 개념 정리 (1) | 2024.09.11 |
---|---|
TIL - 트러블 슈팅: 커뮤니티 리스트 최적화 - 2 (2) | 2024.09.02 |
TIL - Z-index 스태킹 컨텍스트 문제 트러블슈팅 (0) | 2024.08.16 |
TIL - 까다로운 공공 데이터 API 데이터 페칭 트러블 슈팅 (0) | 2024.08.12 |
TIL - 수평 스크롤 문제 해결 (0) | 2024.08.08 |