본문 바로가기

TIL

TIL - 트러블 슈팅: 커뮤니티 리스트 최적화 - 1

이 포스트의 일부 결론은 후속 테스트에서 재평가되었습니다. 업데이트된 정보는 여기를 참조해주세요.

 

TIL - 커뮤니티 리스트 최적화: 렌더링 시간 개선 시도 - 2

TIL - 커뮤니티 리스트 최적화: 렌더링 시간 개선 시도 - 1

fe-jogha.tistory.com

 

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코드 배포환경)

  • 사용자 경험 크게 개선
  • 불필요한 리렌더링 감소로 전반적인 성능 향상
  • 주의: 이 비교는 다른 환경(Vercel vs 로컬)에서 수행되었으며, 이로 인해 결과가 왜곡되었을 수 있습니다. 자세한 내용은 후속 포스트를 참조하세요 

5. 배운 점 및 향후 개선 방향

  • SSR의 중요성 재인식: 로딩 상태보다 초기 콘텐츠 표시가 UX에 더 중요
  • Suspense와 SSR 조합의 가능성 발견
  • 개별 Promise 실패 시 전체 실패 문제 해결 필요