react inifinite scroll 비교 (scroll 이벤트 vs observer api)

iamsummer__·2020년 12월 22일
0
post-thumbnail

예전에는 inifinite scroll을 구현할 때 대부분 scroll 이벤트를 사용하여 구현했다.
요즘은 intersectionObserver api를 사용하여 많이 구현한다.
이 두가지를 비교해보도록 하자.

📚scroll 이벤트 사용한 예제

scroll 할 때마다 이벤트가 발생하기 때문에 throttle 라이브러리를 사용해서 일정시간동안
한번만 이벤트가 발생하도록 구현했다.

debounce: 여러번 발생하는 이벤트 중 마지막 이벤트만 실행 (ex. 검색어)
throttle: 일정시간동안 한번만 이벤트 발생 (ex. 스크롤)

function useInifinite(options: IOptions): boolean {
  const {
    root = window,
    base,
  } = options;

  const [bottom, setBottom] = useState(false);

  /**
   * root가 window객체 여부 확인
   */
  function isWindow() {
    return root.hasOwnProperty('window');
  }

  /**
   * 스크롤 이벤트
   */
  function scrollEvent() {
    const isWin = isWindow();
    const wHeight = isWin ? (root as Window).innerHeight : (root as RefObject<HTMLElement>).current.offsetHeight;
    const dHeight = base.current?.scrollHeight;
    const scrollTop = isWin ? (root as Window).scrollY : (root as RefObject<HTMLElement>).current.offsetTop;

    setBottom(scrollTop >= dHeight - wHeight;
  }

  // 이벤트 리스너 등록
  window.addEventListener('scroll', throttle(scrollEvent, 50))

  return bottom;
}
export default useInifinite;

성능 테스트를 위해 구글 개발자 도구에 있는 performace를 실행해보았다.

A: fps, 초당 프레임수를 나타냅니다. 빨간색으로 표시된 부분은 프레임수가 떨어지는 것을 의미합니다.

B: cpu 사용량을 나타냅니다. 가득차 있으면 최대치로 사용되는 것을 의미합니다.

C: 메인스레스레드, 힙메모리 즉 메모리 사용량을 알 수 있습니다. 또한 빨간색으로 표시가 된 부분은 병목구간을 의미합니다.

c구간 아래에는 힙 메모리에 대한 내용들이 있다.
파란색 그래프가 js heap인데, 메모리 사용량이 증가하면, 가비지 컬렉션(GC)가 수행되게 된다.
GC가 수행되는 동안에는 어플리케이션이 정지된다고 한다.
그러므로 메모리가 늘어나는 구간에서는 메모리 leak을 의심해야한다.
(나중에 기회되면 3snapshot technique 분석해보기!!)

메인 스레드 영역에 빨간색으로 병목구간이 많이 발생하는 것을 확인할 수 있다.
병목구간에는 여러가지 원인들이 있겠지만, scroll 이벤트가 문제가 되는 것을 발견!!

📚intersectionObserver api 사용한 예제

function useInfinite(target: Element, callback: (entries: Array<IntersectionObserverEntry>) => void, options?: IOptions) {
  useEffect(() => {
    if (!target) { return; }

    const observer = new IntersectionObserver(callback, options);

    observer.observe(target);

    return () => { observer.unobserve(target); }
  }, [target, options]);
}
export default useInfinite;

scroll 이벤트 사용한 예제보다 병목구간이 확실히 줄었당!!

문제가 발생하는 다른 부분들도 분석해봐야겟다!! 📚✏️✏️😀😀

profile
개발하는 프론트엔드개발자

0개의 댓글