출처 블로그
- https://scarlett-dev.gitbook.io/all/it/lazy-loading
- https://css-tricks.com/the-complete-guide-to-lazy-loading-images/?fbclid=IwAR2gm3q1j6eZ9rNYo2YcXVz5dsGSJU0xHfsWCTsGl-NqEdT3xFlEJxfLmhs
lazy loading이란?
- 사용자가 웹 페이지를 열면 전체 페이지의 내용을 다운로드 받는다.
- 만약 이용자가 전체 사진 갤러리를 다운로드했지만 첫번째 이미지만 본 후 사용자가 떠났을다면? 웹페이지에서는 메모리 및 대역폭 낭비가 발생한 것이다.
- lazy loading이란 웹 및 응용 프로그램 개발에서 리소스를 미리 로드하는 대신 실제로 필요한 시점으로 로드하도록 지연시키는 기술이다.
장점
- 성능향상 : 미리 다운받는 리소스가 적어지니깐 요청에서 렌더링까지의 시간이 줄어들고 페이지를 빠르게 사용 가능하다.
- 비용절감
사용법
일반적인 로직
- 이미지 태그에 src값 대신 data-src와 같은 data 어트리뷰트를 사용하여 실제 로드할 이미지 주소를 기입한다. (브라우저의 이미지 로드를 막음)
- 이미지가 로드될 시기(주로 뷰 포트에 들어가면)가 되면 이미지를 로드한다.
- 해당 이미지가 로드가 완료되면 data-src에 있는 주소값을 src값으로 셋팅하고 data-src는 삭제한다
방법 1) js 이벤트를 사용해서 이미지 로드 트리거
js scroll 이벤트로 이미지의 위치가 브라우저의 스크롤 높이보다 작다면 data-src를 src 값에 할당하여 이미지를 로드시킨다.
html
<img src="https://ik.imagekit.io/demo/img/image1.jpeg?tr=w-400,h-300" />
<img src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
<img src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image5.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image6.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image7.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image8.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image9.jpeg?tr=w-400,h-300" />
<img class="lazy" data-src="https://ik.imagekit.io/demo/img/image10.jpeg?tr=w-400,h-300" />
- js
document.addEventListener("DOMContentLoaded", function () {
var lazyloadImages = document.querySelectorAll("img.lazy")
var lazyloadThrottleTimeout
function lazyload() {
if (lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout)
}
lazyloadThrottleTimeout = setTimeout(function () {
var scrollTop = window.pageYOffset
lazyloadImages.forEach(function (img) {
if (img.offsetTop < window.innerHeight + scrollTop) {
img.src = img.dataset.src
img.classList.remove("lazy")
}
})
if (lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload)
window.removeEventListener("resize", lazyload)
window.removeEventListener("orientationChange", lazyload)
}
}, 20)
}
document.addEventListener("scroll", lazyload)
window.addEventListener("resize", lazyload)
window.addEventListener("orientationChange", lazyload)
})
- 처음 이미지 3개는 바로 로드하고 나머지는 lazy loading 적용된다
방법2 Intersection Observer API
- intersection observer는 타겟 엘리먼트가 화면에 노출되었는지 여부를 간단하게 구독할 수 있는 api이다.
- 스크롤 이벤트보다 성능상으로 유리하다고 한다.
document.addEventListener("DOMContentLoaded", function() {
var lazyloadImages;
if ("IntersectionObserver" in window) {
lazyloadImages = document.querySelectorAll(".lazy");
var imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy");
imageObserver.unobserve(image);
}
});
});
lazyloadImages.forEach(function(image) {
imageObserver.observe(image);
});
} else {
var lazyloadThrottleTimeout;
lazyloadImages = document.querySelectorAll(".lazy");
function lazyload () {
if(lazyloadThrottleTimeout) {
clearTimeout(lazyloadThrottleTimeout);
}
lazyloadThrottleTimeout = setTimeout(function() {
var scrollTop = window.pageYOffset;
lazyloadImages.forEach(function(img) {
if(img.offsetTop < (window.innerHeight + scrollTop)) {
img.src = img.dataset.src;
img.classList.remove('lazy');
}
});
if(lazyloadImages.length == 0) {
document.removeEventListener("scroll", lazyload);
window.removeEventListener("resize", lazyload);
window.removeEventListener("orientationChange", lazyload);
}
}, 20);
}
document.addEventListener("scroll", lazyload);
window.addEventListener("resize", lazyload);
window.addEventListener("orientationChange", lazyload);
}
})
- 하지만 Intersection observer를 지원하지 않는 브라우저(당연히 ie)도 있기 때문에 그땐 스크롤이벤트를 적용시켜야한다.
배경이미지의 경우
- css의 백그라운드 이미지를 none으로 설정 후 뷰포트에 오면 바꿔주는 방식을 쓴다.
#bg-image.lazy { background-image: none; background-color: #F1F1FA; } #bg-image { background-image: url("https://ik.imagekit.io/demo/img/image10.jpeg?tr=w-600,h-400"); max-width: 600px; height: 400px; }
- 위와 같은 예제에선 id가 bg-image인 요소에 lazy클래스를 추가시켜둔다.
- 뷰 표트에오면 lazy 클래스 속성을 삭제시켜서 백그라운드 이미지가 none -> 이미지소스로 적용되게 한다.
그외 팁들 생략
'공부' 카테고리의 다른 글
실용적인 프론트엔드 테스트 전략 - 2 (0) | 2020.12.09 |
---|---|
실용적인 프론트엔드 테스트 전략 - 1 (0) | 2020.12.09 |
프레젠테이션/컨테이너 컴포넌트 (0) | 2020.12.08 |
타입스크립트 (0) | 2020.12.07 |
리액트 (0) | 2020.12.06 |