[JavaScript] lodash throttle로 이벤트 호출 횟수 제한하기
포스트
취소

[JavaScript] lodash throttle로 이벤트 호출 횟수 제한하기

들어가며

프론트엔드 개발을 하다 보면 scroll, resize, mousemove처럼 짧은 시간 안에 아주 많이 발생하는 이벤트를 다룰 때가 있습니다.

이때 이벤트가 발생할 때마다 무거운 로직을 실행하면 성능 문제가 생길 수 있습니다.

이런 상황에서 사용할 수 있는 도구가 throttle입니다.


throttle이란?

throttle은 일정 시간 동안 함수가 너무 자주 실행되지 않도록 제한하는 기법입니다.

예를 들어 1초에 한 번만 실행되도록 설정하면, 이벤트가 수십 번 발생해도 함수는 최대 1초에 한 번만 실행됩니다.

스크롤 위치 추적이나 브라우저 크기 감지처럼 주기적으로 실행되면 충분한 작업에 잘 어울립니다.


lodash 설치하기

1
npm install lodash

또는 yarn을 사용한다면 다음 명령어로 설치할 수 있습니다.

1
yarn add lodash

기본 사용법

1
2
3
4
5
6
7
8
9
import { throttle } from "lodash";

const logScroll = () => {
  console.log("scroll event", window.scrollY);
};

const throttledLogScroll = throttle(logScroll, 1000);

window.addEventListener("scroll", throttledLogScroll);

위 코드는 스크롤 이벤트가 계속 발생해도 logScroll이 1초에 한 번 정도만 실행되게 만듭니다.


옵션 사용하기

lodash throttle은 실행 시점을 제어할 수 있는 옵션을 제공합니다.

1
2
3
4
const throttledLog = throttle(logScroll, 1000, {
  leading: true,
  trailing: true,
});

leading은 첫 호출 시 바로 실행할지 정합니다.

trailing은 마지막 호출 이후 한 번 더 실행할지 정합니다.

기본값은 둘 다 true입니다.


React에서 사용하기

React에서는 이벤트 리스너 정리를 함께 해주는 것이 중요합니다.

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
import { useEffect, useMemo } from "react";
import { throttle } from "lodash";

const ScrollTracker = () => {
  const handleScroll = useMemo(
    () =>
      throttle(() => {
        console.log("스크롤 위치:", window.scrollY);
      }, 1000),
    [],
  );

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);

    return () => {
      window.removeEventListener("scroll", handleScroll);
      handleScroll.cancel();
    };
  }, [handleScroll]);

  return <div style=>스크롤 테스트</div>;
};

export default ScrollTracker;

cleanup에서 이벤트 리스너를 제거하고 cancel()도 호출하면 예약된 trailing 실행까지 정리할 수 있습니다.


debounce와의 차이

throttle과 debounce는 자주 비교됩니다.

구분throttledebounce
실행 방식일정 시간마다 실행이벤트가 멈춘 뒤 실행
어울리는 상황scroll, resize, mousemove검색 입력, 자동 저장, 유효성 검사

스크롤 중 계속 위치를 확인해야 한다면 throttle이 어울립니다.

입력이 끝난 뒤 한 번만 실행하고 싶다면 debounce가 어울립니다.


마무리

throttle은 너무 자주 발생하는 이벤트의 실행 횟수를 일정 시간 단위로 제한해줍니다.

스크롤, 리사이즈, 마우스 이동처럼 연속적으로 발생하는 이벤트에 사용하면 성능 부담을 줄일 수 있습니다.

React에서 사용할 때는 이벤트 제거와 cancel() 호출까지 함께 정리해두면 더 안전합니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

[React] Zustand persist로 새로고침 후에도 상태 유지하기

[JavaScript] lodash debounce로 이벤트 과도 호출 방지하기