«   2024/11   »
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 26 27 28 29 30
Archives
Today
Total
Recent Posts
Recent Comments
관리 메뉴

뉴히의 개발 로그

[TIL] 20230709 - Throttling & debouncing / lodash 라이브러리 본문

개발일지/TIL

[TIL] 20230709 - Throttling & debouncing / lodash 라이브러리

뉴히 2023. 7. 9. 19:57

[ Throttling ]

Leading Edge : 이벤트가 일어난 첫번째에 function을 일으킴

Trailing Edge : 이벤트가 일어났을 때 어느정도 Delay를 두고 마지막에 function을 일으킴

Leading & Trailing Edge : dealy의 처음과 마지막에 function을 일으킴

const throttle = (delay) => {
        if (timerId) {
            // timerId가 있으면 바로 함수 종료
            return;
        }
        setState(!state);
        console.log(`API요청 실행! ${delay}ms 동안 추가요청 안받음`);
        timerId = setTimeout(() => {
            console.log(`${delay}ms 지남 추가요청 받음`);
            timerId = null;
        }, delay);
    };

 

[ debouncing ]

짧은시간 계속해서 이벤트를 발생시키면 이벤트 핸들러를 호출하지 않고 있다가 마지막이벤트로부터 일정시간 지난 후 이벤트를 한번만 호출

ex)입력값 실시간 검색, 화면 resize 이벤트

// 반복적인 이벤트 이후, delay가 지나면 funciton
    const debounce = (delay) => {
        if (timerId) {
            clearTimeout(timerId);
        }
        timerId = setTimeout(() => {
            console.log(`마지막 요청으로부터 ${delay}ms지났으므로 API요청 실행!`);
            timerId = null;
        }, delay);
    };

 

[ 메모리 누수 ] 

메모리 누수란 페이지 이동전에 setTimeout으로 인해 타이머가 작동중인 상태에서 페이지 이동이 일어났을시, clearTimeout이 안된상태에서 페이지 이동으로 컴포넌트는 언마운트 되었지만 setTimeout 타이머는 메모리를 차지하고 동작하고 잇는 경우.

=> useEffect에 return문으로 언마운트 될때 ~해달라 요청이 가능. return에 clearTimeout으로 메모리 지워주면됨

useEffect(() => {
        return () => {
            // 언마운트 시 (home이라는 컴포넌트가 사라질때 어떠한 동작 가능)
            if (timerId) {
                clearTimeout(timerId);
            }
        };
    }, []);

 

[ debounce -> lodash 라이브러리 사용하기 ]

 

패키지 설치

yarn add lodash

 

디바운스 코드

    // lodash 없이 구현
    const debounce = (callback, delay) => {
        let timerId = null;
        return (...args) => {
            // 클로저 함수, 외부 timerId를 참조
            if (timerId) clearTimeout(timerId);
            timerId = setTimeout(() => {
                callback(...args);
            }, delay);
        };
    };
    

    const handleSearchText = useCallback(
        debounce((text) => {
            setSearchText(text);
        }, 2000),
        []
    );
 // 디바운싱 lodash 사용
    const handleSearchText = useCallback(
        _.debounce((text) => {
            setSearchText(text);
        }, 2000),
        []
    );

debounce 할때는 useCallback 으로 메모이제이션 해줘야함

렌더링이 다시 일어나도 새롭게 함수가 리턴되는게 아니라 이전을 기억하고 그대로 적용가능

ex. 타자를 쳤을때 하나씩 따라오는게 아니고 단어단위로 setState됨