디바운싱과 쓰로틀링

2023. 8. 3. 15:36프로그래밍 언어/JavaScript

카카오페이에서 새로 배운 내용 기록.

밤(bam.chae)께서 목돈계산기/투자계산기 QA를 진행해주셨는데 슬라이더를 빠르게 이동시킬 경우 슬라이더가 멈춰버리는 현상이 이슈로 등록되었다.

슬라이더를 통해 금액값을 입력받고, 해당 값을 쿼리스트링으로 관리하도록 했는데 이 부분에서 따로 최적화를 하지 않아서 슬라이더를 빠르게 이동시킬 경우 지나친 Set 함수 호출로 인해 멈추는 것으로 확인되었다.

UI팀 레츠(lets.go)께서 쓰로틀링이나 디바운싱을 적용하면 될 것 같다고 아이디어를 주셔서 해당 개념에 대해 먼저 알아보았다.

 

운영에는 수정 후 배포했다.

 


디바운싱(Debounce)

연속으로 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것

 

바운싱 현상(bouncing)

: 전자 회로 스위치의 신호 이상 상태에서 온 것으로, 스위치를 눌럿다 떼는 과정에서 전압이 불규칙적으로 들어가 전류의 흐름이 비정상적으로 일어나는 현상을 뜻함. 디바운싱 작업을 해주면 더이상 불규칙적인 전류의 흐름이 발생하지 않는다.

 

검색어 자동완성 기능

검색어 자동완성 API를 예로 들어보자, '콘서트'라는 검색어를 입력하기 위해서는 사용자가

'ㅋ', '코', '콘', '콘ㅅ', '콘서', '콘섵', '콘서트' 와 같이 키보드 입력을 하게된다.

만약, 키 입력 하나하나마다 검색어 자동완성 API를 호출할 경우 총 7번의 요청을 하는 셈이다. 특히 한글의 경우 조합형 언어이기 때문에 '콘섵' 처럼 불필요한 요청이 포함된다.

이와같은 낭비를 줄이기 위해 디바운싱을 사용한다.

 

const DEBOUNCE_TIMEOUT = 50;

const Calculator = () => {
	...
    
	const queryParams = useRecoilValue(calculatorQueryParams);
    const [sliderValue, setSliderValue] = useState({
        monthlyInvestment: monthlyInvestment, // 월 투자 금액
        targetRateOfReturn: targetRateOfReturn, // 목표 수익률
    });
    const navigateParams = useNavigateParams();

    const [timer, setTimer] useState<NodeJS.Timeout>(); // debounce timer

	useEffect(() => {
    	setSliderValue({
        	monthlyInvestment: monthlyInvestment,
            targetRateofReturn: targetRateOfReturn,
        });
  	}, [monthlyInvestment, targetRateOfReturn]);

    ...

    const handleMonthlyInvestmentSliderChange = (value: number) => {
        setSliderValue({ ...sliderValue, monthlyInvestment: value });

        // debounce - 마지막 호출만 실행
        if (timer) {
            clearTimeout(timer);
        }

        const newTimer = setTimeout(async () => {
            try {
                await navigateParams(
                    ROUTE.PATH.UTIL.CALCULATOR.MAIN,
                    { ...queryParams, monthlyInvestment: value.toString() },
                    true,
                )
            } catch (error) {
                throw error;
            }
        }, DEBOUNCE_TIMEOUT);
        setTimer(newTimer);
    };
	
    // targetRateOfReturn(목표 수익률) 슬라이더에 대한 핸들러도 똑같이 만들어주면 된다.
    
    return (
    	...
        
        <MonthlyInvestmentSlider
        	value={sliderValue.monthlyInvestment}
            onChange={handleMonthlyInvestmentSliderChange}
        />
        <TargetRateOfReturnSlider
        	value={sliderValue.monthlyInvestment}
            onChange={handleTargetRateOfReturnSliderChange}
        />
        
        ...
    );
}

export default Calculator;

 

 

 

쓰로틀링(Throttling)

마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것

 

scroll을 움직이면 수많은 scroll 이벤트가 발생한다. 이벤트 리스너등을 통해서 해당 이벤트가 발생할 때마다 어떤 작업을 수행하도록 설정했다면, 해당 작업이 매우 빈번하게 실행하게되어 퍼포먼스에 영향을 끼치게 된다.

이럴 경우 쓰로틀링을 사용하여 1초에 한 번, 또는 200ms에 한 번씩만 실행되도록 제한을 둔다.

 

 


Reference

 

 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

논리 부정 연산자 - 느낌표 한 개(!)와 두 개(!!)  (1) 2023.10.11
slice, substr, substring 비교  (0) 2023.08.28
이벤트 전달 방식  (0) 2022.09.26
클로저(Closure)  (0) 2022.09.22
호이스팅(Hoisting)  (0) 2022.09.22