
무한스크롤을 구현하던 중, 스크롤이 가장 아래에 도달했을 때 다음 내용을 API에 요청하는 작업에서 이슈가 발생했었다.
스크롤을 내리다가 맨 아래에 도달한 시점에 API를 딱 한 번만 호출을 해야하는데, 4~5번씩 호출하고 있었던 것이다. 이러면 서버에도 무리가 가고, 같은 데이터를 여러번 요청해서 화면에도 같은 내용이 여러 개 표시가 되게 됐다.
이를 해결할 수 있는 방법으로 2가지를 생각하게 됐다.
첫 번째 방법은 지금 API 응답을 기다리고 있는지 표시하는 변수를 하나 두는 것이다.
viewModelScope.launch {
try {
_isPostListLoading.emit(true)
// API에 데이터를 요청하는 작업
_isPostListLoading.emit(false)
} catch (e: Exception) {
_postListUiState.emit(mutableListOf())
}
}
}
이런 식으로 isPostListLoading에 API 요청을 처리 중인지 체크하고, 스크롤이 최하단에 도달했을 때 해당 값이 false인 경우에만 요청을 해주면 된다!
최종적으로 이 방법을 이용해서 문제를 해결했는데, 이 방법 이외에도 해결할 수 있는 방법이 있어서 기록해두려고 한다.
Throttle과 Debounce라는 게 있는데, 연속적인 실행을 제한할 때 사용하는 방법으로 실제 내가 겪은 이슈와 같은 상황에서도 많이 활용된다고 한다.
각각의 차이를 설명하자면,
내가 겪은 무한스크롤 이슈에서 사용하기에 적합한 건 Debounce이다.
무한스크롤이 구현되는 방식이, n개의 데이터를 먼저 보여주고 스크롤이 내려가면 다음 데이터를 요청하는 것인데. 이때 cursor 값을 전달해서 내가 다음으로 받아야 할 값이 뭔지를 서버에게 알려주게 된다.
요청 후에는 다음 cursor가 함께 response되고, 다음 요청에서 해당 cursor값을 request 하면 되는 것이다.
첫 번째 이벤트 실행 후 2초동안 요청되는 이벤트를 무시한다고 할 때
첫 번째 값 요청을 하고 2초 안에 아주 빠르게 스크롤을 내려버린다면?
바로 다음 데이터를 요청해야 하는데, 2초가 지나지 않아 해당 요청을 무시해버리게 된다.
그러면 다음 데이터를 받아오지 못하는 문제가 발생하는 것이다.
2초 동안 쌓인 요청 중 마지막 요청만 서버에 실제로 보내기 때문에
그 사이에 cursor 값이 갱신되지 않고,
조금 늦게 요청이 들어갈 수는 있어도 누락시키는 데이터는 없게 된다.
늦게 요청될 수 있는 문제도 2초가 아니라 더 짧게 줄이면 해결될 수 있을 것이라 생각한다.
이번에는 Throttle과 Debounce를 사용하지 않고도 해결된 문제였지만, 다음에 이걸 이용할 수 있는 부분이 생긴다면 바로 적용해볼 수 있게 해야겠다!