Skip to content

Intersection Observer API for Infinite Scroll

Intro

무한스크롤 리팩토링을 진행하면서 Intersection Observer API 에 대해 알게 되었는데 작업할 땐 React의 라이브러리를 사용했지만 기본 WEP API 사용법도 간단해서 API에 대해서도 알아보고, scroll event로 처리했을때와 어떤 차이점이 있는지 알아보았다.


1. Intersection Observer API란?

root 엘리먼트와 target 엘리먼트의 교차점을 관찰하여 교차점의 변경사항을 비동기적으로 관찰하는 방법을 제공한다.

어떤 경우에 사용하는지?

  • 페이지 스크롤시 Lazy-loading 이 필요할때
  • 무한 스크롤 구현
  • 광고 수익률 계산을 위해 광고 가시성을 파악할 때
  • 사용자가 결과를 볼 수 있는지에 따라 작업 또는 애니메이션을 수행할지에 대한 여부를 결정할 때 출처 - MDN.

2. 사용 방법

javascript
let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0,
};

let observer = new IntersectionObserver(callback, options);

let target = document.querySelector('#listItem');
observer.observe(target);

생성자 키워드를 통해 인스턴스를 생성하고, target 요소를 인식할때 수행할 callbackoptions 를 인자로 넘기는 것을 볼 수 있는데 options 에는 어떤 기능이 있는지 각각 살펴보았다.

2.1) Options

root

target 의 부모 요소중 교차 여부를 판단할 대상을 설정한다. 기본값은 null 로, 별도로 설정하지 않으면 기본값이 적용되어 문서의 뷰포트를 기준으로 대상 요소의 변화를 관찰한다.

rootMargin

root 의 margin 값을 설정해주는 옵션으로 기본값은 0이다. 이름 그대로 margin을 통해 root 요소 범위를 확장할 수 있으며, 단 값 입력시 단위를 꼭 입력해 주어야 한다.

threshold

roottarget 의 교차가 이루어짐을 판단하는 기준으로 0에서 1까지 설정 가능하다. 기본값은 0이며, 만약 0.9로 설정할 경우 target 이 90%만큼 보여질 때 교차되었다고 판단한다.

  • threshold를 0으로 설정했을 때target이 viewport에 들어오는 순간 인식 target이 viewport에 들어오는 순간 인식
  • threshold를 0.9로 설정했을 때target이 90% 보여졌을 때 인식 target이 90% 보여졌을 때 인식

직접 확인해보니 threshold 가 0일때는 viewporttarget 이 보여지는 순간 바로 인식하는 것을 확인할 수 있었고, 0.9일때는 90% 보여졌을 때 인식하는 것을 확인할 수 있었다.


3) React-intersection-observer

Intersection Observer API 는 브라우저에서 제공되는 WEB API이기 때문에 별도 라이브러리를 설치할 필요 없이 사용할수 있지만, React에서 해당 API를 hook 형태로 간편하게 사용할 수 있는 라이브러리가 있어 사용해 보았다.

javascript
import { useInView } from 'react-intersection-observer';

function MyComponent() {
  const [ref, inView] = useInView();

  useEffect(() => {
    if (inView) {
      setPageNumber((prev) => prev + 1);
    }
  }, [inView]);

  return <div ref={ref}>{inView ? 'target 보인다' : 'target 안보인다'}</div>;
}

React에서는 target 이 되는 element에 ref를 달아서 target을 모니터링하고, target 요소가 root 와 교차되는 시점에 inViewtrue 로 변한다.

보통 useEffect 로 스크롤이 리스트의 상단 또는 하단에 닿을때마다 pageNumber 를 증감시켜 그에 따라 단어를 삭제하고 받아올 수 있도록 구현한다.


4) Scroll Event 와 Intersection Observer API 차이점

4.1) Scroll Event 처리

observer API를 사용하지 않고 특정 element가 보이는 순간 어떤 동작을 수행해야 할 경우 scroll 이벤트를 등록하고 스크롤이 해당 element 위치에 도달한 순간 콜백함수를 등록하는 방법을 사용할 수 있다.

하지만 스크롤 이벤트로 직접 처리할 경우 고려해야 할 점이 있다.

대화형 사이트에서 갱신하고 난 이후의 경우와 같이 브라우저가 웹 페이지의 위치와 기하학적 구조를 다시 계산할 때 리플로우가 발생합니다. 그 다음에는, 브라우저가 웹 페이지를 다시 그려 결과적인 시각적 갱신을 표시하는 리페인트가 따라옵니다. Reflow - MDN

스크롤 이벤트는 동기적으로 실행되며 이동할때마다 이벤트가 발생하면서 레이아웃을 다시 계산해야 하는 리플로우가 발생하고, 이후 리페인트 과정을 거치면서 다시 그려지는데 이는 비용이 매우 큰 작업이므로 성능 저하에 주의해야 한다. 이런 문제점들을 개선하려 쓰로틀링, 디바운싱을 이용해 성능 개선을 하기도 한다.

4.2) Intersection Observer API

해당 API는 스크롤 이벤트와 다르게 비동기 적으로 실행되어 메인 스레드에 영향을 주지 않으며 관찰자 기반으로 가시성 변경 모니터링이 가능하다.

  • 관찰자 기반 이벤트 기반이 아닌, 관찰자 기반 방식을 사용하여 요소의 가시성 변경에 대한 이벤트를 직접 처리하는것이 아닌 모니터링 후 콜백 함수를 실행한다.
  • 여러 요소 모니터링 가능 여러 요소에 event 처리가 필요할 때 scroll event를 사용할 경우 일일히 이벤트 핸들러를 추가해줘야 하지만 observer api는 한번에 여러 요소의 가시성 모니터링이 가능하다.
  • 비동기 콜백 함수는 비동기적으로 실행되어 메인 스레드에 영향을 주지 않고 모니터링이 가능하다.

4.3) 결론

특성Intersection Observer APIScroll Event
실행 방식비동기적 (Asynchronous)동기적 (Synchronous)
리플로우 발생 여부XO
관찰 대상 요소 감지요소가 뷰포트(root) 내부로 들어오거나 나갈 때 감지 가능요소의 스크롤 위치에 따라 감지 가능
여러 요소 동시 감지가능일반적으로 하나의 스크롤 이벤트에 여러 요소를 관찰하기 어려움

IronTrain Tech Blog