Skip to content

버튼 중복 클릭에 의해 사용자 경험이 저하되는 문제해결 #177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 9, 2025

Conversation

Kyxxn
Copy link
Member

@Kyxxn Kyxxn commented Mar 8, 2025

#️⃣ 연관된 이슈


⏰ 작업 시간

예상 시간 실제 걸린 시간
2 3

📝 작업 내용

  • 책 생성 및 수정하기 버튼에 대한 스로틀 처리
  • 홈에서 추억 만들기 버튼에 대한 스로틀 처리
  • 기록 마치기 버튼에 스로틀 처리

📸 스크린샷


📒 리뷰 노트

학습 목표

사용자 경험 증대를 위한 Debounce와 Throttle 개념을 익히고,

본 예제에서는 위 내용을 통해 버튼 중복 클릭을 방지하고자 한다.


학습 내용

개요

기록소 프로젝트에서 “책 만들기” 버튼이 여러 번 클릭되어 하나의 책만 만들어져야 하는데, 여러 개의 책이 만들어지는 것을 보았다.

다른 버튼도 ?! 해서 막 눌러보니 다른 버튼들도 마찬가지였다.

중복으로 버튼이 눌리는 것을 방지하기 위해 머리속으로 생각해보면,

버튼이 눌린 순간, 0.N초간 여러 번 눌리더라도 한 개만 처리하면 될 것 같다.

그래서 요즘은 반응형 프로그래밍을 위한 프레임워크들, Combine이나 RxSwift에서 Debounce와 Throttle이라는 오퍼레이터를 제공해준다.

우리는 이 오퍼레이터를 통해서 이벤트 방출을 제어할 수 있다.

중복 버튼 눌림을 위한 방법

1. Debounce

이벤트가 들어온 후, 일정 시간만큼 이벤트가 들어오지 않을 때 마지막 이벤트를 방출.

텍스트필드에 Debounce를 3초로 걸었다고 가정해보자.

그럼 사용자가 더 이상 입력하지 않는 시점부터 3초 후에 이벤트를 발행한다.

Apple을 입력할 건데 각 알파벳을 2초마다 입력한다면,

A → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨

Ap → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨

Appl → 2초 → e 입력 = 3초 안 지남 = 이벤트 발송 안 됨

Apple 입력 끝 → 3초 후 이벤트 발송

2. Throttle

일정 시간동안 이벤트가 한 번만 방출.

위 Debounce와 다르게 Throttle은 일정 기간 동안에는 한 번만 이벤트가 발생하도록 제한한다.

이때 이벤트 발생을 가장 마지막, 즉 최근에 들어온 이벤트를 방출할 지 말지를 lastest 파라미터를 통해 선택할 수 있다.

같은 예제로 보자면,

A → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨

Ap → 1초 → 3초지남 = 이벤트 발송

Ap → 1초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨

App → 2초 → 3초 지남 = 이벤트 발송됨 → l 입력

이런 느낌이다.

스로틀과 디바운스의 차이는 일정 시간 간격으로 마지막 이벤트를 방출해주는 차이.

3. 반응형 프로그래밍을 위한 프레임워크가 없었던 시절은?

Combine가 없던 iOS 13버전 이전이나, RxSwift가 없던 때에는 어떻게 했을 지 궁금해서 고민해봤다. 아마 버튼 자체를 못 누르게 하거나, 시간을 직접 제어하지 않았을까?

버튼을 탭하면 즉시 isEnabled = false 로 만든다거나 isUserInteractionEnable = false 를 설정하고, 로직이 끝나면 true로 만드는 게 있을 것 같다.

또, Date()를 시작해서 시간을 직접 비교하는 게 있을듯 하다.

Gㅛ수PT님도 그렇게 말하시긴 하네요

기록소 프로젝트에 적용

악의적으로 버튼을 광클하는 유저가 있을 수도 있고, 한 번 클릭했는데 결과가 바로 안 보여서 짧은 시간 내에 두세 번 클릭했을 수도 있다.

우리 프로젝트는 네트워크 요청을 따로 하지 않기 때문에 버튼 클릭에 따른 요청이 엄청 오래 걸리지 않는다.

위 내용을 정리하면 Debounce는 마지막 이벤트 후 일정 시간이 지나야 실행되도록 하는 것이고, Throttle은 일정 시간 동안 이벤트를 한 번만 허용하도록 하는 것이다.

책 만들기 버튼과 같이 사용자가 버튼을 빠르게 여러 번 누르더라도 한 번의 작업만 실행되어야 하는 상황에서는, 즉시 첫 번째 클릭에 반응하고 그 이후 짧은 시간 동안 추가 클릭은 무시하는 것이 필요하다. 이 경우에는 Throttle 방식을 선택하는 것이 적합하다고 생각했다.

  • debounce는 버튼을 계속 누르는 사용자가 있을 때, 눌렸는지 안 눌렸는지 사용자 경험이 감소함

Debounce는 버튼이 눌리고 더 이상 안 눌릴 때 요청을 보내는 경우 일테니까 이 경우랑은 조금 다른 것 같아 Throttle로 결정했다.


참조 링크

https://0urtrees.tistory.com/365

https://green1229.tistory.com/178

https://green1229.tistory.com/290

https://green1229.tistory.com/291

@Kyxxn Kyxxn added the 🛠️ Fix 오류, 버그 수정 label Mar 8, 2025
@Kyxxn Kyxxn requested a review from k2645 March 8, 2025 07:23
@Kyxxn Kyxxn self-assigned this Mar 8, 2025
@Kyxxn Kyxxn linked an issue Mar 8, 2025 that may be closed by this pull request
@Kyxxn Kyxxn requested a review from iceHood March 8, 2025 07:23
Copy link
Collaborator

@k2645 k2645 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throttle이랑 debounce에 대해서 자세히 PR description에 작성해주셔서 이해하기 너무 좋았습니다 .ᐟ.ᐟ 수고하셨어요 ~ 👍👍

Copy link
Collaborator

@iceHood iceHood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시...
학습 자료까지 만들어 주는 당신은... 역시...

@Kyxxn Kyxxn merged commit 59286a6 into develop Mar 9, 2025
2 checks passed
@Kyxxn Kyxxn deleted the feature/button-debounce branch March 9, 2025 09:15
@iceHood iceHood mentioned this pull request Mar 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🛠️ Fix 오류, 버그 수정
Projects
None yet
Development

Successfully merging this pull request may close these issues.

버튼 중복 이벤트 발생 방지
3 participants