-
Kotlin Flow에서의 Debounce와 Throttle 기법안드로이드 2025. 3. 25. 22:25728x90반응형
Kotlin에서는 Flow를 활용하여 비동기적으로 이벤트를 처리할 수 있으며, 이벤트가 지나치게 자주 발생하는 경우 이를 제어하는 다양한 기법이 필요합니다.
Debounce와 Throttle은 이러한 상황에서 유용하게 사용되는 기법으로, 불필요한 작업을 줄이고 성능을 최적화하는 데 큰 도움이 됩니다.
본 글에서는 이 두 기법의 개념과 이를 Kotlin Flow에서 어떻게 적용할 수 있는지에 대해 살펴보겠습니다.
1. Debounce와 Throttle 기법이란?
Debounce
Debounce는 연속된 이벤트 중 마지막 이벤트만 실행되도록 처리하는 기법입니다.
일정 시간 동안 추가적인 이벤트가 발생하지 않으면, 그때서야 마지막 이벤트를 처리하게 됩니다.
즉, 빠르게 발생하는 여러 이벤트 중에서 마지막 이벤트를 처리하고자 할 때 유용합니다.
사전적 의미📚
Debounce는 "반동을 없애다" 또는 "충격을 완화하다"라는 의미를 가지며, 과도한 반복적인 반응을 없애기 위한 방식입니다.
주요 사용 사례👉🏻
- 검색 자동완성: 사용자가 검색어를 입력할 때마다 서버 요청을 보내는 대신, 입력이 멈춘 후 마지막 검색어만 서버로 보내 불필요한 요청을 방지합니다.
- 실시간 입력 처리: 실시간 유효성 검사나 필터링에서, 입력이 끝날 때까지 기다린 후 최종적으로 처리합니다.
Throttle
Throttle은 이벤트가 일정 시간 간격으로만 실행되도록 제한하는 기법입니다.
이벤트가 자주 발생하더라도 지정된 시간 간격마다 한 번만 처리되며, 그 사이의 이벤트는 무시됩니다.
사전적 의미📚
Throttle은 "조절하다" 또는 "속도를 늦추다"라는 의미를 가지며, 흐름의 속도를 제한하는 방식입니다.
주요 사용 사례👉🏻
- 버튼 클릭 방지: 버튼을 너무 자주 클릭하는 것을 방지할 때, 일정 시간 간격으로 한 번만 처리합니다.
- 스크롤 최적화: 스크롤 이벤트가 자주 발생할 수 있지만, 일정 간격으로만 이벤트를 처리하여 성능을 최적화합니다.
반응형2. Kotlin Flow에서 Debounce와 Throttle 구현하기
Kotlin의 Flow에서는 debounce와 throttle을 쉽게 구현할 수 있습니다. 우선 debounce부터 살펴보겠습니다.
Debounce 구현 예시
Kotlin의 Flow에서 제공하는 debounce 함수는 연속적인 이벤트 중 마지막 이벤트만 처리하는 기능을 제공합니다.
예를 들어, 검색창에서 사용자가 타이핑을 할 때마다 서버에 요청을 보내는 경우, debounce를 사용하여 입력이 끝날 때만 서버에 요청을 보낼 수 있습니다.
Debounce 예시 코드
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val searchFlow = MutableSharedFlow<String>() // 입력 이벤트 스트림 // debounce(500): 500ms 동안 추가 입력이 없으면 마지막 입력만 처리 searchFlow .debounce(500) .collect { query -> println("서버 요청: 검색어 = $query") } // 사용자가 빠르게 입력하는 시뮬레이션 launch { listOf("코", "코틀", "코틀린").forEach { searchFlow.emit(it) delay(200) // 빠르게 입력되는 상황 } } }
- debounce(500): 이 코드에서는 사용자가 "코", "코틀", "코틀린"을 빠르게 입력한다고 가정합니다. debounce는 입력 후 500ms 동안 추가 입력이 없으면 마지막 입력인 "코틀린"만 처리합니다.
- emit: MutableSharedFlow를 사용해 이벤트를 방출하고, 이를 debounce로 처리합니다.
Throttle 구현 예시
Throttle은 일정 시간 간격마다 이벤트가 실행되도록 제한합니다.
예를 들어, 사용자가 버튼을 빠르게 클릭할 때, 한 번만 처리되도록 Throttle을 적용 할 수 있습니다.
Throttle 예시 코드
import kotlinx.coroutines.* import kotlinx.coroutines.flow.* fun main() = runBlocking { val clickFlow = MutableSharedFlow<Unit>() // throttleFirst(1000): 1000ms마다 한 번만 실행 clickFlow .throttleFirst(1000) .collect { println("버튼 클릭 이벤트 처리!") } // 사용자가 빠르게 클릭하는 시뮬레이션 launch { repeat(5) { clickFlow.emit(Unit) delay(300) // 사용자가 빠르게 클릭하는 상황 } } } // throttleFirst 확장 함수 구현 fun <T> Flow<T>.throttleFirst(windowDuration: Long): Flow<T> = flow { var lastTime = 0L collect { value -> val currentTime = System.currentTimeMillis() if (currentTime - lastTime >= windowDuration) { lastTime = currentTime emit(value) } } }
- throttleFirst(1000): 이 코드에서는 사용자가 300ms 간격으로 버튼을 클릭하지만, throttleFirst(1000)을 적용하여 1000ms마다 한 번만 처리됩니다.
- throttleFirst 확장 함수는 이벤트가 발생한 시점에서 windowDuration만큼 간격을 두고 실행하도록 합니다.
728x90
본 글을 통해 Kotlin Flow에서 Debounce와 Throttle 기법을 쉽게 이해하고, 실제 프로젝트에서 어떻게 활용할 수 있는지 알게 되기를 바랍니다.
부족한 글 읽어주셔서 감사합니다.
728x90반응형'안드로이드' 카테고리의 다른 글
Jetpack Compose 이해하기 (2장) - Jetpack Compose의 기본 개념과 Composable 함수 (0) 2025.04.04 Jetpack Compose 이해하기 (1장) - 선언형 UI vs 명령형 UI (0) 2025.04.03 Maverick - MVI Framework 톺아보기 (0) 2025.01.14 [Android] WebView Bridge Thread 에러 (0) 2022.07.26 [Android] Clean Architecture란 (0) 2022.05.30