
ํ๋ก ํธ์๋์์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ด ํ์ํ ๋๊ฐ ๋ง๋ค.
์์ ์ scroll ์ด๋ฒคํธ๋ฅผ ์ง์ ๊ฐ์งํด์ ์ฒ๋ฆฌํ์ง๋ง,
์ง๊ธ์ ๋ ์ฑ๋ฅ ์ข๊ณ , ๊ฐ๋จํ๊ฒ ๊ตฌํ ๊ฐ๋ฅํ API๊ฐ ์๋ค.
๋ฐ๋ก Intersection Observer API๋ค.
์์๊ฐ ๋ทฐํฌํธ(๋๋ ํน์ ๋ถ๋ชจ ์์)์ ๊ต์ฐจ๋๋ ์ง์ ์ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์งํ๋ ๋ธ๋ผ์ฐ์ API
์ฆ, ํ๋ฉด์ ๋ณด์ด๊ธฐ ์์ํ๋์ง ๊ฐ์งํ๋ ๋ฐ ์ต์ ํ๋ API๋ค.
์คํฌ๋กค ์ด๋ฒคํธ์ ๋ฌ๋ฆฌ ์ฐ์์ ์ธ ์ด๋ฒคํธ ํธ๋ฆฌ๊ฑฐ ์์ด ํจ์จ์ ์ผ๋ก ๊ฐ์ง ๊ฐ๋ฅํ๋ค.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('์์๊ฐ ํ๋ฉด์ ๋ณด์');
}
});
});
observer.observe(document.querySelector('#target'));
entries: ๊ด์ฐฐ ๋์ ์์๋ค์ ๊ต์ฐจ ์ํ ๋ชฉ๋กentry.isIntersecting: ์์๊ฐ ํ๋ฉด ์์ ์๋์ง ์ฌ๋ถentry.intersectionRatio: ๋ณด์ด๋ ๋น์จ (0 ~ 1)new IntersectionObserver(callback, {
root: null, // ๊ด์ฐฐ ๊ธฐ์ค (null์ด๋ฉด viewport)
rootMargin: '0px 0px -100px 0px', // ์ฌ๋ฐฑ ์ง์
threshold: 0.5 // 50% ์ด์ ๋ณด์ผ ๋ ํธ๋ฆฌ๊ฑฐ
});
const observerRef = useRef<IntersectionObserver | null>(null);
const targetRef = useRef(null);
useEffect(() => {
observerRef.current = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
loadMore();
}
});
if (targetRef.current) {
observerRef.current.observe(targetRef.current);
}
return () => {
observerRef.current?.disconnect();
};
}, []);
โ
targetRef์ ๊ฑธ๋ฆฐ ์์๊ฐ ํ๋ฉด์ ๋ณด์ด๋ฉด loadMore() ํธ์ถ๋จ
<img data-src="real-image.jpg" class="lazy" />
const images = document.querySelectorAll('.lazy');
const io = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src;
obs.unobserve(entry.target);
}
});
});
images.forEach(img => io.observe(img));
โ ๋ทฐํฌํธ์ ๋ค์ด์ค๋ฉด ์ด๋ฏธ์ง ๋ก๋ฉ ์์, ์ฑ๋ฅ ์ต์ ํ์ ํ์
| ํญ๋ชฉ | scroll ์ด๋ฒคํธ | Intersection Observer |
|---|---|---|
| CPU ๋ถํ | ๋์ (๊ณ์ ํธ๋ฆฌ๊ฑฐ๋จ) | ๋ฎ์ (๋น๋๊ธฐ ๊ฐ์ง) |
| ์ฑ๋ฅ | ์ค๋กํ๋ง ํ์ | ๊ธฐ๋ณธ์ ์ผ๋ก ํจ์จ์ |
| ๊ตฌํ ๋์ด๋ | ๋น๊ต์ ๋ณต์กํจ | ๋งค์ฐ ๊ฐ๋จ |
| ์ฌ์ฉ์ฑ | ๋ชจ๋ ์์ ์ง์ ์ถ์ ํ์ | Observer 1๊ฐ๋ก ์ฌ๋ฌ ์์ ์ถ์ ๊ฐ๋ฅ |
์์ ์ ๋ฌดํ ์คํฌ๋กค ๋ง๋ค ๋ scrollTop, offsetHeight ๊ฐ์ ๊ณ์ฐ์
๋งค๋ฒ ํ๋ฉด์ ์ค๋กํ๋ง๋ ๊ฑธ๊ณ ๋ณต์กํ๊ฒ ์งฐ๋ค.
๊ทธ๋ฐ๋ฐ Intersection Observer๋ฅผ ์๊ฒ ๋ ํ์๋
์ฝ๋๋ ๊ฐ๋จํ๊ณ , ์ฑ๋ฅ๋ ์ข๊ณ , ์ ์ง๋ณด์๋ ์ฌ์์ก๋ค.
์ค์ ๋ก Next.js์์ ์ด๋ฏธ์ง lazy loading ๊ธฐ๋ณธ ์ฒ๋ฆฌ๋ ์ด ๋ฐฉ์์ผ๋ก ์๋ํ๋ค๋ ๊ฑธ ์๊ณ
๋๋์ฑ ์ ๋ขฐ๊ฐ ์๊ฒผ๋ค.
๐ "์คํฌ๋กค ์ถ์ , ๋ ์ด์ ์ง์ ํ์ง ๋ง์. Intersection Observer๊ฐ ๋ค ํด์ค๋ค."