얼렁뚱땅 개발

[개념 잡기] Debounce & throttle 본문

개념 잡기

[개념 잡기] Debounce & throttle

maan_duu 2022. 4. 5. 02:39

이벤트가 무수히 많이 일어나게 된다면? 

 

 

화면이 미친듯이 리렌더링 된다!

ex) 검색을 할때마다(onChange 할때마다) 연관검색어를 계속해서 찾는다면 (리렌더링을 계속 하면)..... 난리난ㄴ다.....ㅎ

 

Debouncethrottle는, 
=> 이벤트가 반복적으로 실행될 때 콜백의 실행을 효과적으로 줄여준다 ! 


1. Debounce

; 이벤트가 들어온다면 일정시간 기다렸다가 수행

- 일정시간을 1초라 가정해 보자! 이벤트 입력을 하고 1초를 기다리는데, 1초가 안끝났을 때 다른 이벤트가 들어온다면??

=> 그 순간부터 다시 1초를 기다린다. 즉 앞에 들어왔던 이벤트는 자동으로 취소된다.

=> 즉, 1초를 온전히 기다리게 된 마지막 이벤트를 실행! 

 

ex) 연관검색어(타이핑이 완전히 끝난 시점에 다 보여줌) 

스크롤같은 경우엔 스크롤을 멈춰야 비로소 데이터가 나타나므로 적절 x

 

- 시간이 많이 걸리는 작업이 자주 실행되지 않도록 함수를 호출하는 시간을 제한. 

 

2. throttle

; 일정 시간동안 일어난 이벤트를 모두 모아서 주기적으로 1번씩 실행 

- 1초가 끝나기 전에 다른 이벤트가 들어온다면 취소 시키지 않고 가지고 있다가 가장 최근 것을 실행시켜준다. 

=> 즉, 이벤트를 누적해 쌓아두다가 가장 최근 것을 실행! 

 

ex) 스크롤로 데이터 볼 때, 계속해서 데이터를 나타내줌으로 적절 o

[사용 예시]

import React from 'react';
import _ from 'lodash'; //debounce와 throttle포함

const Search = () =>{

    const onChange = (e) =>{
        console.log(e.target.value);
    }

    const debounce = _.debounce((e)=>{
        console.log(e.target.value);
    }, 1000); //몇 초 동안(1초) => 기다렸다가 뜸! 

    const throttle = _.throttle((e)=>{
        console.log(e.target.value);
    },1000); //누적되어 쌓이다가 가장최근거를 뱉어냄! 

    return(
        <div>
            <input type='text' onChange={throttle}/>
        </div>
    )
}

export default Search;

 

그런데, useState와 onChange를 이용해 input값을 가져올 때 debounce와 throttle를 쓰게 된다면 입력한 값 만큼 횟수로 찍히게 된다. 

 

why? 함수형 컴포넌트이기 때문! 즉, 리렌더링이 될 때마다 함수들이 모두 초기화 되기 때문이다. 

 

 

 

그렇다면 함수형에선, 재렌더링이 일어날 때는 어떻게 사용할 수 있을까?

 

useCallback() 을 사용하자! 

: 함수 메모이제이션

=> 즉, 어디에 저장을 해서 리렌더링 되더라도 초기화 되지 않게 해준다. 

 

- useCallback 의 첫 번째 인자에는 실행할 함수를 넣어주고,

- 두 번째 인자에는 함수를 초기화할 인자 값을 넣는다. 

=> 즉, 두 번째 인자의 값이 변경되면 첫 번째 함수는 초기화되며 재생성된다. 

 

[사용 예시]

import React from 'react';
import _ from 'lodash'; //debounce와 throttle포함

const Search = () =>{
    
    const [text,setText] =React.useState('');
    
    const debounce = _.debounce((e)=>{
        console.log('debounce ::: ', e.target.value);
    }, 1000); //몇 초 동안(1초) => 기다렸다가 뜸! 

    const throttle = _.throttle((e)=>{
        console.log('throttle ::: ', e.target.value);
    },1000); //누적되어 쌓이다가 가장최근거를 뱉어냄! 
	
    //첫번째; 작동시킬 함수를 넣고,
    //두번째; 함수를 초기화할 조건을 넣는다(이 곳에 인자 값이 변경되면 첫 번째 함수를 재생성!!)
    //=> 리렌더링이 계속 되어도 이미 저장을 해놨기에 초기화되지 않아 제대로 debounce를 실행! 
    const keyPress = React.useCallback(debounce,[]); 

    const onChange = (e) =>{
        setText(e.target.value);
        keyPress(e)
    }


    return(
        <div>
            <input type='text' onChange={onChange} value={text}/>
        </div>
    )
}

export default Search;

 

3. Lodash 

yarn add lodash

- 자바스크립트의 유틸리티 라리브러리로 debounce와 throttle 기능 제공!