Search
📖

버튼 및 검색 기능의 Debounce, Throttle 기법 추가

Intro

1.
구현 되어있는 기능의 문제점들
2.
Debounce, Throttle
3.
Debounce, Throttle 적용 및 주의사항

문제점 :

1. 버튼 기능들의 대한 문제점

앞서 개선한 버튼들의 기능을 Optimistic UI 기법으로 사용했더니 생기는 문제점이 발생했다.
// ex) 좋아요 버튼을 예시로 했을때 1. 사용자가 좋아요 버튼을 클릭 2. 서버에 신호가 전달 3. 서버에서 응답을 보내기 전 다시 아용자가 다시 한번 버튼을 클릭
Dart
복사
이러한 문제 때문에 서버에서 데이터를 받아오기 전부터 좋아요 버튼을 눌러버려 데이터가 꼬여버려 서버에서 에러를 받거나 정상적이지 않는 데이터를 받을 수 있다.

2. 검색 기능들의 대한 문제점

검색 입력 중 입력하는 문자 그대로 서버에 신호를 보내기 때문에 과부하 발생 가능성이 생겼다.
해당 기능들의 성능을 최적화하고 불필요한 작업을 줄이기 위해 입력 이벤트를 개선할 필요가 있다.

How to

Debounce, Throttle

1번과 2번을 해결하려면 여러번 실행되는 문제들을 한번만 실행되게 하면 되기 때문에 Debounce, Throttle을 적용 한다.
Debounce, Throttle을 사용하는 이유는 말그대로 불필요하게 여러번 입력 되는 이벤트를 막아 아래와 같은 이점이 있다.
1. 성능 최적화: 이벤트가 매우 자주 발생하는 경우, 예를 들어 스크롤이나 입력 이벤트, 서버 요청이나 DOM 업데이트 등은 많은 리소스를 소모할 수 있다. 디바운싱과 쓰로틀링을 사용하면 불필요한 이벤트 처리를 줄여 성능을 최적화할 수 있다. 2. 서버 부하 감소: 특히 입력 이벤트에 대해 서버 요청을 보내는 경우, 디바운싱을 사용하면 불필요한 서버 요청을 줄일 수 있어 서버 부하를 감소시킬 수 있다. 3. 사용자 경험 개선: 디바운싱과 쓰로틀링을 사용하면 이벤트 처리의 부드러움을 유지할 수 있고, 과도한 처리가 발생하지 않도록 하여 사용자 경험을 개선할 수 있다.
Dart
복사
Throttle: 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것. 즉 일정 시간 동안 1번만 발생한다.
ex) 스크롤 이벤트, 버튼 이벤트
Debounce: 연이어 호출되는 함수들 중 마지막 함수만 호출하도록 하는 것. 즉 마지막 이벤트를 기준으로 일정 시간이 지나면 이벤트를 1번만 발생한다.
ex) 검색 이벤트

Debounce, Throttle 적용하기

패키지를 이용하여 적용하면 타이머를 따로 선언하지 않고 편하게 사용이 가능하다.

Throttle 적용

간단하게 각 사용하는 버튼 위젯들의 extension을 사용하여 개발한다.
extension InkWellExtension on InkWell { InkWell throttle() { return InkWell( onTap: () { EasyThrottle.throttle( 'inkWellThrottle', const Duration( milliseconds: 500, ), onTap!, ); }, child: child, ); } }
Dart
복사
이렇게 extension을 설정한 다음,
InkWell( onTap: () { }, ).throttle(),
Dart
복사
이렇게 버튼을 사용할때 간단하게 throttle사용이 가능하다.

Debounce 적용

debouncer의 타이머 시간을 걸고 컨트롤러의 이벤트 리스너를 달아 사용이 가능하다.
final debouncer = Debouncer<String>(Duration(milliseconds: 200)); textEditingController.addListener(() => debouncer.value = textEditingController.text); debouncer.values.listen((search) => submitSearch(search));
Dart
복사

Debounce, Throttle 적용 주의사항

적절한 시간 간격 설정: 너무 짧은 시간 간격은 효과를 줄 수 없고, 너무 긴 시간 간격은 사용자 경험을 저하시킬 수 있다. 일반적으로 300ms~500ms 정도가 적당하다고 한다.
사용자 피드백: 디바운스를 사용하면 즉각적인 반응이 없을 수 있으므로 사용자에게 입력이 처리 중임을 알리는 시각적인 피드백을 제공하는 것이 좋다. 예를 들면 로딩을 걸거나, Optimistic UI로 먼저 UI를 변경하여 알리는 방법이있다.
한계 관리: 스로틀의 경우, 지정된 시간 간격 내에 발생한 이벤트 중 첫 번째 이벤트만 처리하므로, 간격 내에 많은 이벤트가 발생하면 일부 이벤트가 누락될 수 있다. 이는 데이터 손실로 이어질 수 있으므로 중요 이벤트는 별도로 처리할 필요가 있다.
메모리 관리: 디바운스와 스로틀 함수는 일반적으로 타이머를 사용하므로, 타이머가 제대로 정리되지 않으면 메모리 누수가 발생할 수 있다. 이벤트 해제 시 타이머도 함께 해제하는 것이 중요하다.