참고
- 자바스크립트: IntersectionObserver (1) 이미지 lazy-loading 구현
- jQuery: 제이쿼리 이미지 지연 로딩(lazy loading) 플러그인 (jQuery Lazy)
- 자바스크립트: 무한 스크롤 (스크롤 이벤트 이용, 라이브러리 없이)
intersectionObserver를 사용하지 않고 마우스 스크롤 이벤트를 이용해 이미지 지연 로딩(lazy loading)을 하는 방법입니다.
이미지 지연 로딩이란 웹 페이지를 렌더링할때 이미지를 불러오지 않고 사용자가 특정 영역을 클릭하거나 스크롤을 하여 이미지 영역이 눈에 보이는 뷰포트(viewport) 안에 들어왔을 때 이미지를 로딩하여 낮은 인터넷속도에서도 쾌적한 로딩을 하기 위한 기법을 말합니다.
여기서는 마우스의 스크롤 이벤트를 사용하며, 이미지 영역이 뷰포트에 들어왔을 때 이미지를 로딩합니다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Load lazy image by scroll-height</title> <style> .img-box { height: 500px; border: 1px solid black; } .img-box img { height: 500px; } </style> </head> <body> <!-- 초기 화면에 들어오는 이미지는 not lazy, 화면 밖에 있는 이미지는 lazy--> <div class="img-box"> <img src="https://i.ibb.co/N7tQQNC/1-Chrysanthemum.jpg"> </div> <div class="img-box"> <img src="https://i.ibb.co/MB0whn7/2-Desert.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/jJ9nV4n/3-Hydrangeas.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/QcKyxtR/4-Jellyfish.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/D78YHNc/5-Koala.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/HP0QKQR/6-Lighthouse.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/6J3L9Kb/7-Penguins.jpg"> </div> <div class="img-box lazy"> <img data-src="https://i.ibb.co/Rj41Xwr/8-Tulips.jpg"> </div> <script> // .. 스크립트 삽입 .. // </script> </body></html>
function debounce(callback, limit = 100) { let timeout return function(...args) { clearTimeout(timeout) timeout = setTimeout(() => { callback.apply(this, args) }, limit) } } const imgBoxes = document.querySelectorAll(".img-box.lazy") const loadLazyImg = debounce(e => { // clientHeight : 웹 브라우저 창의 높이 // scrollTop : 현재 스크롤된 부분의 맨 위의 높이 // scrollHeight : 문서의 총 높이 (= 스크롤의 총 높이) // (이미지 lazy) 해당 이미지가 현재 스크롤 화면에 들어옴 : clientHeight + scrollTop >= box.offsetTop // (참고: 무한스크롤) 스크롤의 마지막에 도달 : clientHeight + scrollTop >= scrollHeight // window.innerHeight = clientHeight const { clientHeight, scrollTop, scrollHeight } = e.target.scrollingElement imgBoxes.forEach(box => { if (box.offsetTop < clientHeight + scrollTop) { const $img = box.querySelector("img") $img.src = $img.dataset.src $img.classList.remove("lazy") } }) }, 200) // ===== 이미지 로딩 ===== document.addEventListener("scroll", loadLazyImg) // 출처: https://velog.io/@boh001/Infinity-Scrolling
- 마우스 스크롤 이벤트를 사용하기 때문에 최적화를 위해 콜백 실행시 debounce 또는 throttle 함수를 사용합니다.
clientHeight + scrollTop
는 현재까지 스크롤된 영역까지의 높이를 말하며box.offsetTop
은 이미지 영역의top
위치를 말합니다. 현재까지 스크롤된 영역 안에box.offsetTop
이 있다면 이미지가 뷰포트에 나타난 상태이므로 이미지 지연 로딩을 시작하고, 아직 스크롤된 영역 밖에 있다면 뷰포트에 나타나지 않은 상태이므로 대기합니다.data-src
속성에 이미지 주소를 저장하고, 지연 로딩 시작시data-src
의 주소를src
속성에 지정합니다.- 처음부터 나타나는 이미지 몇 개는 지연 로딩을 하지 않는것이 좋습니다. (SEO 관련)
출처: https://velog.io/@boh001/Infinity-Scrolling
0개의 댓글