์ค์ ์ด๋ฏธ์ง๊ฐ ํ๋ฉด์ ๋ณด์ฌ์ง ํ์๊ฐ ์์ ๋, ๋ก๋ฉ์ ํ ์ ์๋ ๊ธฐ์
์ฆ, ์น ํ์ด์ง ๋ด ๋ฐ๋ก ๋ก๋ฉ์ ํ์ง ์๊ณ ๋ก๋ฉ ์์ ์ ๋ค๋ก ๋ฏธ๋ฃจ๋ ๊ฒ
Image๋ฟ ์๋๋ผ SPA๋ด JSํ์ผ ๋ก๋์๋ ์ฌ์ฉํ ์ ์์
์ฑ๋ฅํฅ์์ ์น ์ฌ์ดํธ ๋ก๋ฉ ์๊ฐ, ์ฑ๋ฅ ๊ด๋ฆฌ ์ธก๋ฉด์์ ๊ฐ์ฅ ์ค์ํ ์์์ ๋๋ค.
lazy loading์ ํตํด ๋ฆฌ์์ค ์์ฒญ์ ์ค์ด๊ณ , ๋ค๋ฅธ ๋ฆฌ์์ค๋ฅผ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ด, ์ ์ ๊ฐ ํ์ด์ง๋ฅผ ํ์ธํ ๋ ๋ ๋นจ๋ฆฌ ํ์ธํ๊ณ ์ด์ฉํ ์ ์์ต๋๋ค.
ํต์ ๋น์ฉ ๊ด์ ์ ์์ด ์ ์ฝํ ์ ์์ต๋๋ค. ๋๋ถ๋ถ์ ์ด๋ฏธ์ง ์ ๋ฌ ๊ด๋ จ์ ์ ์ก ๋ฐ์ดํธ ์์ ๊ธฐ๋ฐํ์ฌ ์ฒญ๊ตฌ๋ฉ๋๋ค. ์ด๋ฏธ์ง๊ฐ ๋ณด์ฌ์ง์ง ์์ผ๋ฉด ์ ๋ ๋ก๋ฉํ์ง ์์ผ๋ฏ๋ก, ํ์ด์ง ๋ด ์ ๋ฌํ ์ฉ๋์ด ์ค์ด๋ค์ด ์ ์ก๋น์ฉ์ด ๊ฐ์๋ฉ๋๋ค.
Image tag
์ด๋ฏธ์ง๋ ํ๊ทธ๋ด src
์์ฑ์ ํตํด ์ด๋ฏธ์ง๋ ๋ก๋๋ฉ๋๋ค. ์ฆ ๋ธ๋ผ์ฐ์ ๋ด ์ด๋ฏธ์ง๊ฐ src
์์ฑ์ ๊ฐ์ง๊ณ ์์ผ๋ฉด ์ด๋ฏธ์ง๋ ๋ฌด์กฐ๊ฑด ๋ก๋๋ฉ๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ณ ์ ์ด๋ฏธ์ง์ url
์ ๋ค๋ฅธ ์์ฑ์ ํ ๋นํ์ฌ ์ด๋ฏธ์ง์ ๋ก๋ฉ์ ์ง์ฐ์ํต๋๋ค.
์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<img src="https://sampleImage.jpg">
โ
<img data-src="https://sampleImage.jpg">
์ดํ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ฉํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฏธ์ง๊ฐ ๋ทฐํฌํธ์ ๋ค์ด์์ ๋ ๋ก๋ฉํ ์ ์๋๋ก ํ์ธ๋์ด์ผ ํฉ๋๋ค.
scroll
, resize
, orientationChange
์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์์๋ก Image lazy loading์ด ๋ฐ์ํฉ๋๋ค
์ด๋ฏธ์ง๋ฅผ ๋ชจ๋ ์ฐพ์
๋ทฐํฌํธ๋ก ๋ค์ด์จ ์ด๋ฏธ์ง ํ๋ณ
src์์ฑ์ ๋ฃ์ด ์ด๋ฏธ์ง ๋ก๋
lazyํด๋์ค ์ ๊ฑฐ
์ด๋ฒคํธ ๋ฆฌ์ค๋ ํธ๋ฆฌ๊ฑฐ ์ ๊ฑฐ
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)) {
//src์์ฑ์ data-src์์ฑ ๊ฐ ๋ฃ์ด ์ด๋ฏธ์ง ๋ก๋
img.src = img.dataset.src;
//lazyํด๋์ค ์ ๊ฑฐ
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);
});
์์๊ฐ ๋ทฐํฌํธ์ ๋ค์ด์ค๋ ๊ฒ์ API๊ฐ ๊ฐ์งํฉ๋๋ค. ๋ค์ ์์์ ๋ฐ๋ผ Image lazy loading์ด ๋์ํฉ๋๋ค.
isIntersecting
์์ฑ์ผ๋ก data-src์ url์ src์์ฑ์ผ๋ก ๋ณ๊ฒฝ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);
});
}
})
Intersection Observer๋ฅผ ํ์ฉํ์์ ๋, ์ฌ์ฉ์๊ฐ ์คํฌ๋กค ์ ์ด๋ฏธ์ง๊ฐ ๋๋ฆฌ๊ฒ ๋ํ๋์ง ์์ต๋๋ค. ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ํ์ฉํ ๋ฐฉ์์์ timeout์ ํ์ฉํ์ฌ ์ฝ๊ฐ์ ๋๋ ์ด๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๋ฏธ์ง์ loading
์์ฑ์ ์ถ๊ฐํ๋ฉด lazy loading์ด ์ฝ๊ฒ ๊ตฌํ๋ฉ๋๋ค. ์๋๋ loading์์ฑ์ ์ฌ์ฉํ๋ ๊ฐ์
๋๋ค.
ํ์ง๋ง, ๋ก๋ฉ์ด ์ง์ฐ๋ ์ด๋ฏธ์ง๊ฐ ๋ถ๋ฌ์์ง ๋, ๋ค๋ฅธ ์ฝํ ์ธ ๋ด์ฉ์ด ๋ฐ๋ ค๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด์, ๋ฐ๋์ width/height ์์ฑ์ imgํ๊ทธ ๋๋ inline style๋ก ์ง์ ๊ฐ์ ์ง์ ํด์ผํฉ๋๋ค.