lazy loading이란
-
모든 이미지들을 한번에 불러와서 로딩이 오래 걸리는 현상을 방지하고, 웹 성능을 향상시키기 위해 뷰포트에 아직 등장하지 않은 이미지는 로딩을 지연시켰다가 불러오는 방식이다.
-
성능 향상과 비용 감소에 효과적이다.
구현 코드
아주 잘 설명된 글이 있어서 보고 따라서 코드를 쳐보면서 이해하려고 해봤다.
웹 성능 최적화를 위한 Image Lazy Loading 기법
먼저 아래 코드들의 html 코드는 이렇다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
img {
background: #f1f1fa;
width: 400px;
height: 300px;
display: block;
margin: 10px auto;
border: 0;
}
</style>
<script src="app.js"></script>
<body>
<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"
/>
</body>
</html>
자바스크립트 이벤트 이용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
document.addEventListener("DOMContentLoaded", () => {
let lazyLoadImages = document.querySelectorAll("img.lazy");
let lazyLoadThrottleTimeout;
const lazyLoad = () => {
if (lazyLoadThrottleTimeout) {
clearTimeout(lazyLoadThrottleTimeout);
}
lazyLoadThrottleTimeout = setTimeout(() => {
let scrollTop = window.pageYOffset;
lazyLoadImages.forEach((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 API를 이용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
document.addEventListener("DOMContentLoaded", () => {
let lazyLoadImages;
if ("IntersectionObserver" in window) {
lazyLoadImages = document.querySelectorAll(".lazy");
let imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let image = entry.target;
image.src = image.dataset.src;
image.classList.remove("lazy");
imageObserver.unobserve(image);
}
});
});
lazyLoadImages.forEach((image) => {
imageObserver.observe(image);
});
} else {
let lazyLoadThrottleTimeout;
lazyLoadImages = document.querySelectorAll(".lazy");
const lazyLoad = () => {
if (lazyLoadThrottleTimeout) {
clearTimeout(lazyLoadThrottleTimeout);
}
lazyLoadThrottleTimeout = setTimeout(() => {
let scrollTop = window.pageYOffset;
lazyLoadImages.forEach((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);
}
});
Native Lazy Loading
1
2
<img src="example.jpg" loading="lazy" alt="..." />
<iframe src="example.html" loading="lazy"></iframe>
이제는 이미지 속성 중에 loading="lazy"
가 생겼다고 한다.
lazy
: 뷰포트에서 일정한 거리에 닿을 때까지 로딩을 지연eager
: 현재 페이지 위치가 위, 아래 어디에 위치하던 상관없이, 페이지가 로딩되자마자 해당 요소를 로딩auto
: 이 속성은 디폴트로 로딩을 지연하는 것을 트리거. 기본적으로 이것은 loading 속성을 쓰지 않을 것과 같다.
참고자료 Throttle이란