Web APIs는 총 2편의 시리즈로 구성되어 있습니다.
- Intersection Observer API란
- Resize Observer API란
들어가며
실무에서 스크롤을 내리다 특정 시점에 실행되어야 하는 이벤트를 구현하는 일이 있었습니다.
자연스럽게 window scroll 이벤트를 이용해서 작업을 했는데, 더 나은 방법인 Intersection Observer API라는 걸 알게 되면서 적용해 보고 느낀 점을 적어보려 합니다.
Intersection Observer API 란?
구글 번역기로 Intersection Observer를 직역해 보면 ‘교차로 관찰자’라고 합니다. ‘교차로 관찰자’, 너무 직역된 것 같죠? 이해하기 쉽게 의역해 보자면 브라우저의 뷰포트와 타깃 엘리먼트의 교차점을 관찰하는 API라고 합니다. 더 쉽게 말해보면 브라우저에 우리가 지정한 요소가 지금 보이는지 구별하는 기능을 제공한다고 생각하면 됩니다.
앞서 이 API가 더 나은 방법이라고 소개한 이유가 있는데요, 기존 방식인 window의 scroll 이벤트로 구현하게 되면 스크롤을 할 때마다 이벤트가 호출되어서 브라우저 성능에 부담을 줄 수 있습니다. 반면에 Intersection Observer API는 비동기적으로 실행되기 때문에 이런 부담을 줄일 수 있는 장점이 있습니다.
이런 장점으로 인해 mdn 문서에서는 이 API가 필요한 경우 4가지를 말해주고 있습니다.
- 페이지가 스크롤 될 때 이미지 또는 콘텐츠를 지연 로드 시킬 때 → Lazy load
- 스크롤 할 때 점점 더 많은 콘텐츠가 로드되고 렌더링 될 때 → 인피니티 스크롤
- 광고 수익을 계산하기 위해 광고의 가시성을 보고할 때
- 사용자가 결과를 볼 수 있는지에 따른 작업 또는 애니메이션 프로세스
위의 경우 스크롤 이벤트 보다 Intersection Observer API를 통해 구현한다면 좀 더 나은 사용자 경험을 제공할 수 있습니다.
하지만 이런 API도 한계가 있는데요, 보여지는 영역을 정확한 px 값이 아닌 %, 즉 보여지는 비율로만 알 수 있다는 점입니다.
사용 방법
Intersection Observer API를 사용해 보겠습니다. Intersection Observer API는 2개의 인자를 받습니다.
callback과 options입니다.
observer라는 이름으로 IntersectionObserver를 만들어 봅시다.
let options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 0.5,
};
let observer = new IntersectionObserver(callback, options);
observer를 만든 후에는 관찰할 대상 요소를 지정해야 합니다.
let target = document.querySelector('#target'); // 타깃
observer.observe(target);
대상이 threshold에 지정한 임계값을 충족할 때마다 callback 함수가 호출됩니다.
callback 함수는 IntersectionObserverEntry의 객체 목록과 관찰자를 받습니다.
let callback = (entries, observer) => {
entries.forEach((entry) => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
React로 적용한 샘플코드를 통해 확인해 볼 수 있습니다. console 창을 열어 수치를 확인해 보세요. target 영역의 50%가 보이는 순간 색상이 바뀌는 걸 확인해 보실 수 있습니다.
callback
boundingClientRect
타깃 요소의 사각형 정보를 나타냅니다.
intersectionRatio
교차한 영역 정보를 사각형 정보로 나타냅니다.
intersectionRect
교차한 영역의 백분율 정보를 나타냅니다.
isIntersecting
교차한 상태인지 boolean값으로 나타냅니다.
rootBounds
지정한 root 요소의 사각형 정보를 나타냅니다.
target
타깃 요소
time
교차가 시작된 시점을 기록합니다.
options
root
뷰포트로 사용되는 요소입니다. 타깃 요소의 조상을 지정합니다. 지정되지 않았거나 null인 경우 뷰포트가 기본값입니다.
rootMargin
루트 요소의 여백을 지정합니다. css의 margin 속성과 유사한 값을 가질 수 있습니다. 값은 백분율이 될 수도 있습니다. ex) ‘10px 20px 30px 40px’, ‘50%’
threshold
타깃 요소의 가시성 비율을 나타냅니다. 기본값은 0이며 단일 숫자 또는 배열로 나타낼 수 있습니다. 예를 들어 타깃 요소의 50%를 통과할 때 나타나게 하고 싶다면 0.5를 사용하면 됩니다.
실무에서 매번 위의 방법으로 호출하는 것은 비효율적이고 hook을 만들어서 사용하거나 react-intersection-observer 라이브러리를 이용하면 좀 더 편리하게 사용할 수 있습니다.
마치며
Intersection Observer API에 대한 간단한 사용법과 원리를 알아보았는데요. 저는 이런 유용한 API를 아직도 몰랐다는 사실이 좀 부끄러웠고 역시 공부를 해야겠다는 생각이 들었습니다.
또한 스크롤 이벤트를 모두 Intersection Observer API로 대체시킬 수는 없는 한계는 분명히 존재하고 상황에 맞게 적용하면 좋을 것 같습니다.
이 글을 통해서 스크롤 관련 작업 시 해당 API를 활용하여 브라우저 성능을 좀 더 향상하셨으면 좋겠습니다.
감사합니다.