[리팩토링] 카드 리스트 애니메이션 구현 시도(2) - 성능 개선

yoon Y·2022년 3월 29일
0

[2nd_Project] WaffleCard

목록 보기
15/15

useInterval 재실행, 중지 시 재렌더링 방지하기

문제점/결과
isPlayMove상태를 의존하기 때문에 useInterval(스크롤 애니메이션)이 재실행, 중지될 때마다 리렌더링이 발생한다. 이를 막기 위해 ref로 변경 시도했지만 원하는대로 동작하지 않았다..

이유
isPlayMove 상태가 바뀔 때마다 리렌더링되어, 바뀐 상태값을 이용한 새로운 인자값으로 useInterval이 다시 실행되어야하는데 ref.current는 변경되어도 리렌더링이 되지 않기 때문에 useInterval이 재실행되지 않는다.

// 관련 코드만 간추림 //

// WaffleCardsList.tsx
const WaffleCardsList = ({
  ...props
}: WaffleCardsListProps) => {
  ...
  const {
    isPlaying,
    setIsPlaying,
    isIntersecting,
    setObserveTarget,
    moveScrollToFront,
    moveScrollToBack,
  } = useScrollAnimation(cardsListRef.current, [type]);
// useScrollAnimation.ts
const useScrollAnimation = (
  ...
): ReturnTypes => {
  
  const [isPlaying, setIsPlaying] = useState(true);
  
  useInterval(
    () => {
      if (!(observeTargetDom instanceof Element)) return;
      observeTargetDom.scrollLeft += 1;
    },
    isPlaying ? 15 : null, // null일 시 setInterval중지
  );

  return {
    isPlaying,
    setIsPlaying,
    isIntersecting,
    setObserveTarget,
    moveScrollToFront,
    moveScrollToBack,
  }; 
  ...

onMouseOver, onMouseOut 이벤트 버블링 버그

문제점
CardList에 onMouseOver, onMouseOut이벤트를 걸었을 때, 이벤트가 발생되면 이벤트핸들러콜백이 계속해서 실행됐다. 스크롤 이벤트와 같은 경우인줄 알고 throttle을 걸어봤지만 같은 현상이었다.
이유는 이벤트 버블링 때문이었다. 가장 상위 컴포넌트에 이벤트를 걸었을 경우, 하위 자식들에게도 적용이 되기 때문에 이벤트가 자식들 수 만큼 여러 번 발생하는 것이었다. (사실 자식들 수만큼이 아니라 수없이 발생됐지만 정확한 이유는 모르겠다.. 버블링을 이유로 뭔가 꼬인 것 같다)

해결책
버블링이 발생하지 않는 onMouseEnter, onMouseLeave를 사용해서 해결했다!

참고자료

profile
#프론트엔드

0개의 댓글