🌟 배경
프로젝트에서 사용되는 컴포넌트 중 유튜브 Embed url
과 iframe
을 이용해서 해설영상을 보여주는 YoutubeModal
이라는 컴포넌트가 있었습니다. (아래의 빨간 박스 안에 있는 모달)
이 컴포넌트는 url
과 iframe
을 이용해 영상을 보여주는 것 이외에도 다른 스크립트들을 가져오고, 사용자의 특정 동작을 추적하고 기록하는 로직을 포함하고 있어, 상대적으로 사이즈가 큰 컴포넌트입니다.
컴포넌트가 무거운 것에 비해, 해설 영상 링크를 가지고 있는 문제(데이터)들이 많지 않았기 때문에 대부분의 경우에 해당 컴포넌트는 렌더링 되지 않았습니다.
따라서, 해당 컴포넌트에 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
컴포넌트를 사용자에게 조금 더 빠르게 보여 줄 수 있었습니다.