lazy loading이란 페이지를 읽어들이는 시점에 중요하지 않은 리소스 로딩을 나중에 하는 기술이다. (ex. 갤러리 기능능을 하는 앱에서 보여지지 않는 사진들의 이미지를 불러오지 않는다)
<img data-src='https://이미지_주소.jpg'>
src는 비워져있고 해당 이미지 주소에 따른 이미지를 로드하지 않는다.
<img src='example.jpg' loading='lazy'/>
최신 chrome 브라우저에서는 natvie lazy loading을 지원한다. (임베딩 할 이미지에 ‘loading’ 속성만 추가해주면 된다.)
-lazy : 뷰포트에서 일정한 거리에 닿을 때까지 로딩을 지연시킨다.
-eager : 현재 페이지 위치가 위, 아래 어디에 위치하던 상관없이, 페이지가 로딩되자마자 해당 요소를 로딩한다.
-auto : 이 속성은 디폴트로 로딩을 지연하는 것을 트리거합니다. 기본적으로 이것은 loading 속성을 쓰지 않는것과 같다.
const [img, setImg] = useState(
images.map(image => {
return (
process.env.PUBLIC_URL +
`./Images/${image.split('/')[3].split('.')[0]}.jpg`
);
}),
); // 이미지 주소의 배열
const handleImg = e => {
setImg([URL.createObjectURL(e.target.files[0]), ...img]);
}; // 사진 추가
useEffect(() => {
const imgs = document.querySelectorAll('.photo');
const lazyImageObserver = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
const lazyImage = entry.target;
const bound = lazyImage.getBoundingClientRect(); // target의 위치 구하기
console.log(window.innerHeight); // 화면의 높이
console.log(bound.top, bound.bottom); // 화면 상단부터 대상의 처음 위치 값, 화면 상단부터 대상의 끝 위치 값
if (entry.isIntersecting) {
setTimeout(() => {
if (bound.top <= window.innerHeight && bound.bottom >= 0) {
lazyImage.src = lazyImage.dataset.src;
lazyImageObserver.unobserve(lazyImage);
}
}, 500);
}
});
});
imgs.forEach(function (lazyImage) {
lazyImageObserver.observe(lazyImage);
});
}, [img]);
return (
{img.length === 0
? null
: img.map((el, idx) => {
return (
<ImagesContainer key={idx}>
<img
className="photo"
data-src={el}
onClick={() => {
setModalOpened(!ModalOpened);
setImageIndex(idx);
}}
/>
<span
onClick={() => {
deleteImg(idx);
}}
>
×
</span>
</ImagesContainer>
);
})}
)