Hits

🌟 배경

프로젝트에서 사용되는 컴포넌트 중 유튜브 Embed urliframe을 이용해서 해설영상을 보여주는 YoutubeModal이라는 컴포넌트가 있었습니다. (아래의 빨간 박스 안에 있는 모달)

이 컴포넌트는 urliframe 을 이용해 영상을 보여주는 것 이외에도 다른 스크립트들을 가져오고, 사용자의 특정 동작을 추적하고 기록하는 로직을 포함하고 있어, 상대적으로 사이즈가 큰 컴포넌트입니다.
컴포넌트가 무거운 것에 비해, 해설 영상 링크를 가지고 있는 문제(데이터)들이 많지 않았기 때문에 대부분의 경우에 해당 컴포넌트는 렌더링 되지 않았습니다.
따라서, 해당 컴포넌트에 Lazy Loading을 적용해, youtubeModal 컴포넌트를 감싸고 있는 컴포넌트의 렌더링 속도를 최적화 시켜주기로 했습니다.


🌟Lazy Loading, Preloading

Lazy Loading의 경우에는, 리액트에서 제공하는 React.lazy 를 이용해서, 쉽게 구현 할 수 있습니다.

해설영상 링크가 없는 경우에는 YoutubeModal 컴포넌트가 필요하지 않기 때문에, 해설 영상이 있고, 또 해설 영상을 열었을 때만, 해당 컴포넌트의 자바스크립트 파일을 import 하도록 만들었습니다.

const YoutubeModal = React.lazy(
  () => import("src/components/molecules/youtubeModal/youtube_modal")
);
const YoutubeModal = React.lazy(
  () => import("src/components/molecules/youtubeModal/youtube_modal")
);

여기서 하나의 문제점이 발생했는데, 해당 컴포넌트가 무겁다 보니, 해설 영상 버튼을 클릭해서 사용자가 실제, 모달 내부의 콘텐츠를 이용 할 수 있을 때까지 로딩 시간(Suspense의 fallback이 보여지는 시간)이 길다는 점이었습니다.

이를 해결하기 위해, youtubeModal 컴포넌트에 Preloading을 적용하기로 했습니다.

해설영상링크가 없는 경우에는, 해설 영상이라는 버튼이 렌더링 되지 않습니다.

즉, 해설 영상 버튼이 없다면, youtuebModal 컴포넌트를 사용할 일이 없고, 해설 영상 버튼이 있다면, youtubeModal 컴포넌트를 사용 할 수도 있습니다.

Preloading을 적용하기 이전, Preloading 시점을 정해야 했고, 다음 2가지 중 하나의 경우를 선택하기로 했습니다.

  • 해설 영상 버튼이 mount 되는 시점
  • 해설 영상 버튼에 마우스가 올라갔을 때 (Hover)

실제 사용자 들 중 해설 영상 버튼을 클릭해서 해설 영상을 시청하는 사용자가 많지 않다는 사실을 알고 있었습니다. 이에 따라 해설 영상 버튼이 mount 되는 시점이 아닌, 해설 영상 버튼이 Hover 되었을 때, 컴포넌트를 Preloading 하기로 하였습니다.

React에서 Element의 Hover이벤트는 onMouseEnter 이벤트를 통해 감지 할 수 있었습니다. 따라서, onMouseEnter 이벤트에 대한 콜백 함수를 만들고, 해당 함수에서 동적으로 YoutubeModal 컴포넌트를 import 하도록 만들었습니다.

const CommentaryVideoOpenButton = () => {
  const { openModal } = useModals();
 
  const onHoverButton = () => {
    import("src/utils/youtubeModal/youtube_modal");
  };
 
  const onClickButton = () =>
    openModal(MODALS.YOUTUBE_MODAL, {
      url: problem.lectureURL,
    });
 
  return (
    <button
      className={styles.youtubeBtn}
      onClick={onClickButton}
      onMouseEnter={onHoverButton}
    >
      해설 영상
    </button>
  );
};
const CommentaryVideoOpenButton = () => {
  const { openModal } = useModals();
 
  const onHoverButton = () => {
    import("src/utils/youtubeModal/youtube_modal");
  };
 
  const onClickButton = () =>
    openModal(MODALS.YOUTUBE_MODAL, {
      url: problem.lectureURL,
    });
 
  return (
    <button
      className={styles.youtubeBtn}
      onClick={onClickButton}
      onMouseEnter={onHoverButton}
    >
      해설 영상
    </button>
  );
};

결과적으로, Lazy Loading을 통해, YoutubeModal을 사용하는 경우에만, 해당 자바스크립트 파일을 import 하도록 할 수 있도록 하여 번들 파일의 크기를 줄일 수 있었고,
Preloading을 통해, 무거운 YoutubeModal 컴포넌트를 사용자에게 조금 더 빠르게 보여 줄 수 있었습니다.