본 포스트는 프론트엔드 성능 최적화를 보며 개인적으로 정리한 내용이다.
이미지 최적화 기법에는 다양한 방법이 존재한다. 그 중 하나인 Intersection Obeserver API를 사용한 Lazy 로딩에 대해서 알아보도록 하자.
Intersection Obeserver은 루트 요소와 타겟 요소의 교차점을 관찰하고 있다가 교차가 되는 부분인지 아닌지를 판별해주는 기능을 제공한다.
scroll 이벤트와는 다르게 교차 시 reflow를 발생시키지 않아 성능상 유리한 측면이 있다.
이미지를 갖고 있는 카드 컴포넌트에 obeserver을 적용시켜 해당 이미지가 화면에 교차되는 순간 이미지를 불러오는 방식이다.
function Card(props) {
const imgRef = useRef(null);
useEffect(() => {
const callback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
console.log("is Intersecting", entry.target.dataset.src);
// lazy 로딩
// observer가 감지 되었을때 해당 img src에 data-src로 저장해뒀던걸 적용시킨다.
entry.target.src = entry.target.dataset.src;
// 또 다시 observer가 작동되지 않기 위해 oberve를 해지한다.
observer.unobserve(entry.target);
}
});
};
const options = {};
const observer = new IntersectionObserver(callback, options);
observer.observe(imgRef.current);
}, []);
return (
<div className="Card text-center">
<img ref={imgRef} data-src={props.image} />
<div className="p-5 font-semibold text-gray-700 text-xl md:text-lg lg:text-xl keep-all">
{props.children}
</div>
</div>
);
}
export default Card;