throttle(쓰로틀링) 과 debounce(디바운싱)로 성능 향상 시키기

시작하기

사이트 퍼포먼스를 향상 시키기위해서 사용하는 방법 중 하나입니다. 스크롤 혹은 인풋 박스에서 너무 많은 이벤트를 호출하여 불필요한 메모리를 소모하여 퍼포먼스를 떨어뜨립니다. 이 문제를 해결하기 위한 방법으로 Throttling(쓰로틀링)과 debouncing(디바운싱)이 있습니다.

기본 개념

쓰로틀링은 마지막 함수가 호출된 이후 지정한 시간이 지나기 전에 호출되지 않도록 하는 것입니다.
디바운싱은 연속적인 함수호출중 마지막 혹은 맨처음 함수가 호출되는 것입니다.

설정

Lodash 혹은 underscore 패키지에서 지원하는 Throttle과 Debounce를 사용하겠습니다.
npm 기반의 프로젝트로 가정하고 설명을 시작하겠습니다.

프로젝트에 lodash 패키지를 설치합니다.
npm i lodash
그러면 준비가 완료되었습니다.

Scroll에서 Throttle과 Debounce

웹사이트 스크롤을 했을때 한번 호출하고자 하나, 이벤트는 수십개가 호출되는 경우가 있습니다. 이 상황에서 쓰로틀링과 디바운싱을 사용해보며 설명하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let count = {
normal: 1,
throttle: 1,
debounce: 1,
};
const normalScroll = () => {
count = { ...count, normal: count.normal + 1 };
};
const throttleScroll = () => {
throttle(() => {
count = { ...count, throttle: count.throttle + 1 };
}, 500);
};
const debounceScroll = () => {
debounce(() => {
count = { ...count, debounce: count.debounce + 1 };
}, 500);
};

document.addEventListener("scroll", () => {
normalScroll();
throttleScroll();
debounceScroll();
});

위와 같은 코드를 통해서 스크롤을 한다면 이벤트 발생시 기본과 쓰로틀링 디바운싱이 서로 다른 시간에 카운트 한다는 것을 알 수 있습니다.

scroll throttle debounce

1
2
3
4
5
const throttleScroll = () => {
throttle(() => {
count = { ...count, throttle: count.throttle + 1 };
}, 500);
};

쓰로틀링의 첫번째 인자는 실제로 구동이 될 함수입니다. 두번째 인자는 시간으로, 이벤트 발생하는 동안 500ms같격의 시간에 함수를 호출하겟다는 의미입니다

1
2
3
4
5
const debounceScroll = () => {
debounce(() => {
count = { ...count, debounce: count.debounce + 1 };
}, 500);
};

디바운싱의 첫번째 인자도 마찬가지로 실제로 구동이 될 함수입니다. 두번째 인자는 시간으로, 쓰로틀링과 달리 이벤트 발생하는 처음 시작했거나 마지막 500ms이후의 시간에 함수를 딱 한번 호출하겟다는 의미입니다.

다음 인풋에서도 같은 방식으로 사용할 수 있습니다.

Input에서 Debounce

input에서 onchange이벤트를 이용하면 자음과 모음을 각자 입력할때마다 이벤트가 호출됩니다.
처음, ㄱ, ㄴ, ㅏ와 같이 이러한 각 단위는 실제 검색에서는 유용한 데이터를 불러올 수 없습니다.
무의미한 이벤트를 발생시킵니다. 이 부분에서 이벤트를 덜 발생시키기 위해서 Debounce를 사용합니다.

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
31
32
33
34
import React, { useState, useCallback } from "react";
import { debounce } from "lodash";
import "./input.css";

const Input = () => {
const [value, setValue] = useState("");
const [search, setSearch] = useState("");

const delaySetValue = useCallback(
debounce((value) => {
setSearch(value);
}, 500),
[]
);
const handleInputChange = (e) => {
delaySetValue(e.currentTarget.value);
setValue(e.currentTarget.value);
};

return (
<div>
<input
className="input"
type="text"
placeholder="Debounce 입력"
value={value}
onChange={handleInputChange}
/>
<p className="text">{search}</p>
</div>
);
};

export default Input;
  • value: Input에 입력되는 부분입니다.
  • search: debounce를 통해 이벤트 마지막 500ms이후에 등록됩니다.

input debounce

이것으로 input과 scroll에서 throttle과 debounce를 사용하는 방법을 알아 보았습니다.
방금 작성한 예시외에도 다양한 부분에서 throttle 및 debounce를 사용할 수 있습니다. 적절하게 사용하면 api call 횟수가 줄거나 이벤트 호출이 줄어 메모리 절약에 많은 도움이 될 것입니다.

Share