Tech/ReactJS

상세 상품 prefetch로 인한 불필요한 네트워크 요청 해결

닝닝깅 2024. 5. 20. 14:54

📌 문제상황

prefetch 도입 전
prefetch 도입 후

 

- 사용자 경험 향상을 위해 상품 상세 페이지 로딩 시간을 줄이고자 상품 데이터 prefetch 도입

- 전체 상품 조회 페이지에서 상품 썸네일 이미지에 hover 했을 때 상품 데이터 prefetch 하도록 설계

- 마우스 움직임에 따라 불필요한 네트워크 요청 다량 발생

 

 

📌 원인 분석

  const { handlePrefetchProduct } = usePrefetchProduct({ productId: data.id }); // prefetch 커스텀훅
  
  const handleMouseEnter = () => {
    handlePrefetchProduct();
  };
<div
  onClick={onClickItem}
  onMouseEnter={handleMouseEnter}
  className="cursor-pointer"
>
  <!-- 중략 -->
</div>;

- 마우스가 잠깐이라도 스쳐지나간 경우 (ex 스크롤 시) 스쳐간 모든 상품에 대한 데이터 prefetch 동작

 

 

📌 해결 방법 고민

이벤트 발생의 최적화가 필요하다!!!

방법 1) debounce를 활용하여 hover 이벤트 하나로 묶어 prefetch 실행

- 딜레이시간 설정 후 추가 이벤트 발생이 없으면 prefetch 실행

- 추가 이벤트가 발생하는 경우에 타이머를 자동 리셋시켜 prefetch 실행 연기

=> 한계 : 추가 의존성 발생 + 타이머가 내부적으로 관리되기 때문에 제어 권한 없어 세밀한 조정은 불가

 

방법 2) setTimeout를 활용하여 일정시간 이상 머물렀을 때만 prefetch 실행 

- setTimeout으로 hover 이벤트 로직에 딜레이 시간 설정

- 딜레이 시간 내에 마우스를 벗어나는 경우에는 clearTimeout으로 prefetch가 취소되도록 설계

=> ✅ 선택

 

 

📌 문제 해결

onMouseLeave 이벤트 핸들러를 등록하여 이벤트 발생 호출 횟수를 최적화 시킬 수 있었다. 사용자 경험을 해치지 않기 위해 지연시간을 적절하게 조정하는 것이 중요하게 느껴졌다.

let prefetchTimer: ReturnType<typeof setTimeout> | null = null;

const handleMouseEnter = () => {
  prefetchTimer = setTimeout(handlePrefetchProduct, 400);
};

const handleMouseLeave = () => {
  if (prefetchTimer) {
    clearTimeout(prefetchTimer);
    prefetchTimer = null;
  }
};
<div
  onClick={onClickItem}
  onMouseEnter={handleMouseEnter}
  onMouseLeave={handleMouseLeave}
  className="cursor-pointer"
>
  <!-- 중략 -->
</div>;