피트니스 산업과 IT, 그리고 스타트업

IT

플러터, 쓰로틀링과 디바운싱

핏더스트리 2025. 5. 2. 14:32
728x90
반응형

플러터, 쓰로틀링과 디바운싱

Flutter 앱을 만들다 보면 사용자의 입력이 빠르게 반복될 때 어떻게 처리할지 고민해야 할 상황이 자주 생겨요. 예를 들어 검색창에 글자를 입력할 때마다 API 요청을 보내거나, 버튼을 너무 자주 눌렀을 때 중복 동작이 발생하지 않도록 막고 싶을 때가 있죠.

 

이럴 때 자주 사용되는 개념이 바로 ‘디바운싱(Debouncing)’‘스로틀링(Throttling)’이에요. 두 용어는 비슷하게 들릴 수 있지만, 실제로는 적용되는 상황과 동작 방식에 분명한 차이가 있어요. 성능 최적화는 물론, 예기치 않은 버그나 과도한 요청을 방지하기 위해서라도 꼭 알고 있어야 할 개념이죠.

 

이번 글에서는 디바운싱과 스로틀링이 각각 어떤 개념인지, Flutter에서는 어떻게 구현할 수 있는지, 실제로 어떤 상황에 적용하면 좋은지를 정리해볼게요. 오늘은 먼저 디바운싱에 대해 자세히 들여다보겠습니다.

 

 

디바운싱(Debouncing)이란 무엇인가?

디바운싱은 이벤트가 반복적으로 발생할 때, 가장 마지막 이벤트만 처리하도록 지연시키는 방식이에요. 쉽게 말해 “사용자가 입력을 멈춘 다음에야 작업을 수행하도록 기다리는 것”이에요.

 

예를 들어 검색창에 단어를 입력할 때마다 바로바로 서버에 요청을 보내면, 입력하는 매 순간마다 API 호출이 발생해서 과도한 네트워크 요청이 생길 수 있어요. 이런 경우 디바운싱을 사용하면, 사용자가 입력을 멈춘 후 일정 시간(예: 500ms) 동안 아무런 입력이 없을 때만 요청을 보내게 할 수 있어요.

 

Flutter에서는 Timer 클래스를 활용해 간단히 디바운싱을 구현할 수 있어요. 예를 들면 아래와 같은 방식으로요.

Timer? _debounce;

void onSearchChanged(String query) {
  if (_debounce?.isActive ?? false) _debounce!.cancel();
  _debounce = Timer(Duration(milliseconds: 500), () {
    // API 호출 또는 원하는 동작 수행
    performSearch(query);
  });
}

위 코드는 입력이 발생할 때마다 이전 타이머를 취소하고, 새로 500ms 타이머를 설정해요. 사용자가 계속 타이핑을 하고 있으면 동작이 발생하지 않고, 입력이 멈춘 순간부터 500ms가 지난 후에야 검색이 실행되는 구조예요.

 

디바운싱은 검색창 외에도, 텍스트 필드 입력, 스크롤 위치 감지, 창 크기 조절 이벤트 등 빠르게 반복되는 사용자 입력을 통제할 때 매우 유용하게 사용돼요.

 

 

스로틀링(Throttling)이란 무엇인가?

디바운싱이 “마지막 입력만 처리한다”는 개념이라면, 스로틀링은 일정 시간 간격으로만 동작을 허용하는 방식이에요. 즉, 이벤트가 얼마나 자주 발생하든 정해진 시간 간격마다 한 번씩만 실행되도록 제한하는 것이죠.

 

이 개념을 실제 예시로 이해해보면 더 쉬워요. 사용자가 스크롤을 빠르게 움직이는 상황을 생각해볼게요. 스크롤 이벤트는 매우 자주 발생하지만, 매번 실행될 필요는 없어요. 예를 들어, 특정 위치에 도달했을 때만 API를 호출한다거나, 현재 위치에 따라 UI를 업데이트해야 할 때는 이벤트가 너무 자주 호출되면 성능이 떨어질 수 있어요. 이럴 때 스로틀링을 사용하면 일정 주기마다 한 번만 작업이 실행되도록 조절할 수 있어요.

 

Flutter에서 스로틀링을 구현할 때는 DateTime이나 Stopwatch를 활용하는 방식이 대표적이에요. 예를 들어 아래와 같이 사용할 수 있어요.

DateTime? _lastExecuted;

void onScrollEvent() {
  final now = DateTime.now();
  if (_lastExecuted == null ||
      now.difference(_lastExecuted!) > Duration(milliseconds: 300)) {
    _lastExecuted = now;
    // 여기에 실행할 동작을 넣음
    handleScrollUpdate();
  }
}

위 코드에서는 마지막으로 실행된 시간과 현재 시간을 비교해, 300ms가 지나지 않았다면 작업을 무시하고, 일정 시간이 지나면 작업을 실행해요. 이렇게 하면 1초에 수십 번 발생할 수 있는 이벤트를, 1초에 3~4회로 제한할 수 있어요.

 

스로틀링은 디바운싱과 달리 “일정 주기로 반응해야 할 때” 적합해요. 예를 들어,

 

  • 스크롤 위치에 따라 요소를 고정하거나 해제할 때
  • 지도 앱에서 위치가 바뀔 때마다 일정 간격으로 위치 업데이트
  • 센서 이벤트 처리 등

 

이처럼 사용자 인터랙션이 빈번하지만 실시간 반응이 필요하지 않은 경우, 스로틀링은 성능 저하 없이 필요한 작업만 수행하도록 도와주는 강력한 도구예요.

 

 

디바운싱 vs 스로틀링, 언제 어떤 걸 써야 할까?

디바운싱과 스로틀링은 얼핏 비슷해 보이지만, 적용해야 할 상황은 분명하게 다릅니다. 핵심은 “이벤트가 얼마나 자주 발생하느냐”보다, “그 이벤트가 언제 처리돼야 가장 자연스러운가”를 기준으로 판단하는 것이에요.

 

디바운싱은 입력의 마지막 시점에만 동작을 실행하는 방식이에요. 예를 들어 사용자가 검색창에 글자를 입력할 때, 매 글자마다 검색 결과가 나오면 부담스럽고, 쓸모없는 요청만 늘어나겠죠. 이럴 땐 사용자가 타이핑을 마쳤을 때만 요청을 보내는 디바운싱이 정답이에요. 입력이 멈추고 일정 시간(예: 500ms)이 지나야 동작이 실행되니까, 자연스럽고 깔끔한 사용자 경험을 만들 수 있어요.

 

반면 스로틀링은 이벤트가 계속 발생하더라도 일정 간격으로만 처리하는 방식이에요. 예를 들어 스크롤 이벤트처럼 초당 수십 번 발생하는 상황에서 매번 동작을 실행하면 성능 저하가 심해져요. 이런 경우에는 300ms마다 한 번만 처리하는 식으로 주기를 제한해주는 스로틀링이 유리해요. 사용자는 충분히 부드럽게 느끼지만, 시스템은 훨씬 효율적으로 동작하게 되는 거죠.

 

요약하자면,

 

  • 디바운싱은 “입력이 끝난 후” 처리할 때
  • 스로틀링은 “일정 주기마다 지속적으로” 처리할 때
  • 각각 사용하면 됩니다. 두 개념을 적절히 구분해서 사용할 수 있다면, Flutter 앱의 성능과 사용자 경험은 분명 한층 더 향상될 거예요.

 

마치며...

Flutter에서 디바운싱과 스로틀링은 단순한 기술적 디테일처럼 보일 수 있지만, 실제로는 앱의 사용자 경험과 성능을 크게 좌우하는 요소예요. 입력에 즉각 반응하되 과도한 요청은 막고, 불필요한 연산을 줄이되 반응성을 유지하는 이 미묘한 균형을 맞추는 데 꼭 필요한 도구들이죠.

 

이번 글을 통해 두 개념의 차이점과 활용법을 명확히 이해하고, 언제 어떤 상황에 적용하면 좋을지 감이 잡히셨기를 바라요. Flutter는 반응형 UI 프레임워크인 만큼, 이벤트 처리 흐름을 얼마나 잘 설계하느냐가 앱의 완성도를 결정짓는 핵심 중 하나예요.

 

성능이 중요한 화면일수록, 사용자와의 인터랙션이 잦을수록, 디바운싱과 스로틀링을 적극 활용해보세요. 작은 코드 한 줄이 앱 전체의 인상을 바꿀 수 있다는 사실, 꼭 기억하셨으면 좋겠습니다!

728x90
반응형