JavaScript

[JavaScript] Debounce, Throttle, Memoization(성능 최적화 기법)

dearlhy 2025. 2. 22. 22:28

JavaScript 애플리케이션을 개발할 때 성능 최적화는 매우 중요합니다.
특히 이벤트 핸들링, 연산 비용 절감, 불필요한 함수 실행 방지 등의 최적화 기법을 활용하면
웹사이트의 반응성과 효율성을 높일 수 있죠.

이번 글에서는 Debounce, Throttle, Memoization 기법을 차례대로 살펴보겠습니다.

 

1. Debounce (디바운스)

1) 개념

디바운스(Debounce)는 이벤트가 연속적으로 발생할 때, 마지막 이벤트만 실행하도록 제어하는 기법입니다.
사용자의 입력이 멈춘 후 일정 시간이 지나면 함수를 실행하도록 합니다.

2) 사용 사례

  • 검색 입력창 자동완성
    → 사용자가 입력을 멈춘 후 일정 시간이 지나면 검색 API 호출
  • 윈도우 리사이즈 이벤트
    → 창 크기가 조정될 때 마지막 변경 후 일정 시간 후에 레이아웃을 조정
  • 버튼 연타 방지
    → 사용자가 너무 빠르게 버튼을 클릭하는 것을 방지

3) 코드 예제

function debounce(func, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer); // 기존 타이머 제거
    timer = setTimeout(() => func.apply(this, args), delay); // delay 후 실행
  };
}

// 사용 예시: 검색 자동완성
const searchInput = document.getElementById('search');
searchInput.addEventListener(
  'input',
  debounce(() => {
    console.log('🔍 검색 API 호출!');
  }, 300)
);

사용자가 입력을 멈춘 후 300ms 후에만 검색 API 호출

 

2. Throttle (쓰로틀)

1) 개념

쓰로틀(Throttle)은 이벤트가 일정 시간 간격으로만 실행되도록 제한하는 기법입니다.
디바운스와 달리 이벤트가 지속적으로 발생해도 일정한 간격으로 실행됩니다.

2) 사용 사례

  • 스크롤 이벤트 최적화
    → 사용자가 스크롤할 때 일정 간격으로만 이벤트 실행
  • 버튼 클릭 제한
    → 사용자가 특정 버튼을 연타해도 일정 시간마다 한 번만 실행
  • 마우스 이동 감지
    → 마우스가 움직이는 동안 성능 부담을 줄이기 위해 일정 간격으로만 실행

3) 코드 예제

function throttle(func, limit) {
  let lastCall = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      func.apply(this, args);
    }
  };
}

// 사용 예시: 스크롤 이벤트 최적화
window.addEventListener(
  'scroll',
  throttle(() => {
    console.log('📜 스크롤 이벤트 실행!');
  }, 500)
);

스크롤 이벤트가 500ms마다 한 번씩만 실행됨
브라우저 성능 최적화 효과

3. Memoization (메모이제이션)

1) 개념

메모이제이션(Memoization)은 연산 결과를 저장하여 동일한 입력값에 대해 연산을 반복하지 않도록 최적화하는 기법입니다.
즉, 한 번 계산한 결과를 캐싱하여 성능을 개선합니다.

2) 사용 사례

  • 반복적인 연산 최적화
    → 동일한 계산을 여러 번 수행할 때 성능 향상
  • API 요청 캐싱
    → 동일한 API 호출을 여러 번 하지 않도록 캐싱
  • 재귀 함수 최적화 (피보나치 수열 등)

3) 코드 예제

function memoize(fn) {
  const cache = {};
  return function (...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      console.log('⚡ 캐시된 값 반환:', key);
      return cache[key];
    }
    console.log('🔄 새로운 연산 수행:', key);
    const result = fn.apply(this, args);
    cache[key] = result;
    return result;
  };
}

// 사용 예시: 피보나치 수열
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

const memoizedFibonacci = memoize(fibonacci);
console.log(memoizedFibonacci(10)); // 처음 호출 시 계산 수행
console.log(memoizedFibonacci(10)); // 두 번째 호출 시 캐시된 값 반환

동일한 연산을 반복하지 않고 캐시된 값을 반환하여 성능 최적화
연산량이 많은 함수에서 매우 유용

4. 정리: Debounce vs Throttle vs Memoization

기법개념사용 사례

Debounce 마지막 이벤트 발생 후 일정 시간 후 실행 검색창 자동완성, 입력 필드 이벤트 최적화
Throttle 일정 시간 간격으로 실행 스크롤 이벤트, 마우스 이동 감지
Memoization 연산 결과를 저장하여 중복 연산 방지 피보나치 수열, API 캐싱

5. 마무리

오늘은 JavaScript에서 성능 최적화를 위한 3가지 기법을 알아봤습니다.
Debounce는 연속된 이벤트 중 마지막 이벤트만 실행하고,
Throttle은 일정 시간 간격으로 실행하며,
Memoization은 동일한 연산을 피하고 캐싱하여 속도를 개선합니다.

이 기법들을 적절히 활용하면 웹 애플리케이션의 성능을 크게 향상시킬 수 있습니다.