이번에 제가 GDGoC KNU 홈페이지를 개발하면서 react-lazy-observer
패키지를 NPM에 배포하게 되었는데 이와 관련한 고찰과 패키지 소개를 하려 한다.
놀랍게도 배포한 지 일주일 만에 150회가 넘는 다운로드를 기록했다.
블로그 기능에 관련해서 팀원과 개발하면서 고민이 하나 생겼다.
나중에 블로그 글 목록이나 팀 페이지의 포스트들이 쌓이다 보면 인피니티 스크롤을 적용한다고 하더라도 인기글과 어느정도 블로그 글 포스트때문에 성능 이슈가 생길 것 같았다.
그래서 React에서 제공하는 lazy
와 Suspense
로 코드 분할은 가능하지만, 여기에 Intersection Observer API를 결합하면 더 스마트한 지연 로딩이 가능하지 않을까? 라는 생각에서 시작했다.
실제 DOM과 React가 어떻게 상호작용하는지 자세히 살펴보자:
// 1. DOM 요소 참조 설정
const observerRef = React.useRef<HTMLDivElement>(null);
이 단계에서 일어나는 일:
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.disconnect();
}
});
},
{
threshold: 0.3
}
);
여기서 중요한 점:
그래서 시각적으로 보면 이런 흐름이 된다:
초기 상태
스크롤 진행
30% 임계점 도달
setIsVisible(true); // 상태 업데이트 트리거
컴포넌트 로딩
{isVisible ? (
<React.Suspense fallback={fallback}>
{children}
</React.Suspense>
) : (
fallback
)}
observer.disconnect(); // 임무 완료 후 정리
즉시 정리
조건부 실행
if (isVisible) return;
효율적인 DOM 접근
이런 최적화 덕분에 LazyLoad 컴포넌트는 효율적으로 동작하면서도 브라우저 리소스를 아낄 수 있다.
라이트하우스로 성능 측정해보니 몇 가지 재밌는 점을 발견했다:
react-lazy-observer는 꽤 괜찮은 도구지만, 모든 상황에 딱 맞는 건 아니다. 적용하기 전에 잘 고민해보자:
그래도 앞으로 있을 기능에 대해 기술 부채보단 좋지 않을까라는 생각과 뭔가 재미난 고민에 대한 해결책을 구현할 수 있었던 것 같아서 재밌었다.
더 자세한 내용은 npm 패키지 페이지에서 확인할 수 있다.