본문 바로가기
JavaScript

[JavaScript] Debounce와 Throttle: 차이점과 활용 방법

by teamnova 2025. 3. 10.
728x90

Debounce와 Throttle: 차이점과 활용 방법

프로그래밍을 하다 보면 이벤트가 너무 자주 실행되어 성능 저하가 발생하는 경우가 많습니다. 대표적인 예로 스크롤 이벤트, 입력 필드 변화 감지, 창 크기 조절 등이 있습니다. 이런 문제를 해결하는 대표적인 기법이 **Debounce(디바운스)**와 **Throttle(스로틀)**입니다.

이번 글에서는 두 개념의 차이점을 이해하고, 언제 어떤 방식을 사용해야 하는지 실제 코드와 함께 알아보겠습니다.

 

1. Debounce(디바운스)란?

Debounce는 특정 이벤트가 연속적으로 발생할 때, 마지막 이벤트 이후 일정 시간이 지난 후에만 실행되는 기법입니다. 즉, 사용자가 계속해서 입력하거나 행동하는 동안에는 실행되지 않고, 일정 시간이 지나서야 함수가 실행됩니다.

동작 원리
이벤트가 발생하면, 기존 타이머를 초기화하고 새로운 타이머를 설정합니다.
사용자가 입력을 멈춘 후, 지정된 시간이 지나야 함수가 실행됩니다.
입력이 계속 들어오면 타이머가 계속 초기화되므로 실행되지 않습니다.

언제 사용할까?
검색창 자동완성 (사용자가 입력을 멈춘 후 API 요청)
창 크기 조절 이벤트 (사용자가 크기 조절을 멈춘 후 실행)
폼 입력 검증 (사용자가 입력을 마친 후 검증 실행)

 

2. Throttle(스로틀)란?

Throttle는 이벤트가 연속적으로 발생해도 일정한 간격으로만 실행되도록 제한하는 기법입니다. 즉, 특정 시간 간격 내에서는 한 번만 실행되도록 합니다.

동작 원리
이벤트가 발생하면, 실행 시간을 기록합니다.
이후, 지정된 시간이 지나야 다시 실행됩니다.
따라서, 이벤트가 계속 발생해도 일정한 간격으로만 실행됩니다.

언제 사용할까?
스크롤 이벤트 (무한 스크롤 또는 스크롤 위치 감지 최적화)
버튼 클릭 방지 (사용자가 버튼을 연타하더라도 일정 시간 간격으로만 실행)
마우스 이동 감지 (사용자의 마우스 좌표를 일정 간격으로 업데이트)

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Debounce & Throttle - 차이점과 활용 예제</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            height: 200vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background-color: #f4f4f4;
        }
        h1, h2 {
            text-align: center;
        }
        .box {
            width: 250px;
            height: 100px;
            background-color: lightblue;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 20px;
            font-size: 18px;
            font-weight: bold;
            border-radius: 8px;
            box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
        }
        .content {
            max-width: 800px;
            margin: 20px auto;
            padding: 20px;
            background: white;
            border-radius: 10px;
            box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
        }
        ul {
            padding-left: 20px;
        }
    </style>
</head>
<body>
    <div class="content">
        <h1>Debounce & Throttle - 차이점과 활용 예제</h1>
        <p>웹 개발에서 이벤트 처리는 중요한 요소이며, Debounce와 Throttle은 성능 최적화를 위한 핵심 기법입니다.</p>

        <h2>Debounce란?</h2>
        <p>Debounce는 특정 이벤트가 연속적으로 발생할 때, 마지막 이벤트만 실행되도록 지연시키는 기법입니다.</p>
        <ul>
            <li><strong>사용 예:</strong> 검색창 자동완성, 입력 필터링</li>
            <li><strong>이유:</strong> 너무 많은 API 요청 방지</li>
        </ul>

        <h2>Throttle란?</h2>
        <p>Throttle은 일정 시간 간격마다 함수가 실행되도록 제한하는 기법입니다.</p>
        <ul>
            <li><strong>사용 예:</strong> 스크롤 이벤트, 버튼 클릭 방지</li>
            <li><strong>이유:</strong> 과도한 연산으로 인한 성능 저하 방지</li>
        </ul>

        <h2>실제 예제</h2>
        <p>📌 마우스를 움직이면 Debounce 적용, 스크롤하면 Throttle 적용</p>
        <div class="box" id="debounce-box">Debounce</div>
        <div class="box" id="throttle-box">Throttle</div>
    </div>

    <script>
        /**
         * Debounce 함수
         * 지정된 시간(delay) 동안 호출이 없을 경우 마지막 호출만 실행됨.
         */
        function debounce(func, delay) {
            let timer;
            return function(...args) {
                clearTimeout(timer);
                timer = setTimeout(() => func.apply(this, args), delay);
            };
        }

        /**
         * Throttle 함수
         * 지정된 간격(limit) 내에서 최초 호출 후 일정 시간 동안 추가 호출을 막음.
         */
        function throttle(func, limit) {
            let lastCall = 0;
            return function(...args) {
                const now = Date.now();
                if (now - lastCall >= limit) {
                    lastCall = now;
                    func.apply(this, args);
                }
            };
        }

        // DOM 요소 가져오기
        const debounceBox = document.getElementById("debounce-box");
        const throttleBox = document.getElementById("throttle-box");

        // Debounce 적용: 마우스 이동 시 텍스트 변경
        const logDebounce = debounce(() => {
            debounceBox.textContent = "Debounced!";
            setTimeout(() => debounceBox.textContent = "Debounce", 500);
        }, 1000);

        // Throttle 적용: 스크롤 시 텍스트 변경
        const logThrottle = throttle(() => {
            throttleBox.textContent = "Throttled!";
            setTimeout(() => throttleBox.textContent = "Throttle", 500);
        }, 1000);

        // 이벤트 리스너 추가
        document.addEventListener("mousemove", logDebounce);
        document.addEventListener("scroll", logThrottle);
    </script>
</body>
</html>

 

시연영상