-
Notifications
You must be signed in to change notification settings - Fork 0
Chore: 스로틀링 vs 디바운스 - 광클 방지, 무엇이 더 적합할까? #2
Copy link
Copy link
Open
Description
무분별한 클릭(광클)은 ML 데이터 품질을 떨어뜨리는 '노이즈'가 될 뿐만 아니라, 클라이언트와 서버 자원을 불필요하게 소모.
1. 스로틀링 vs 디바운스: 무엇이 더 적합할까?
- 디바운스(Debounce): 클릭이 멈춘 후 일정 시간 뒤에 실행 (연속 클릭의 마지막 한 번만 기록)
- 스로틀링(Throttling): 클릭하는 동안 일정 주기마다 실행 (0.3초에 한 번씩 기록)
- 숨은그림찾기 게임 특성상 사용자가 화면 여기저기를 빠르게 훑으며 누를 수 있으므로, 스로틀링이 더 적합
- 0.3초 주기로 첫 번째 클릭은 즉시 받아들이고, 그다음 0.3초 동안 들어오는 클릭은 무시하는 방식
2. 스로틀링을 적용한 클릭 핸들러 코드 (Next.js/React)
useRef 활용 → 간단하고 성능 좋은 스로틀링 로직 구현
'use client';
import { useRef, useState } from 'react';
export default function GameCanvas() {
const [logs, setLogs] = useState<any[]>([]);
const lastClickTime = useRef<number>(0);
const THROTTLE_TIME = 300; // 0.3초
const handleClick = (e: React.MouseEvent) => {
const now = Date.now();
// 1. 스로틀링 체크: 마지막 클릭으로부터 0.3초가 지났는지 확인
if (now - lastClickTime.current < THROTTLE_TIME) {
console.log("광클 방지: 클릭 무시됨");
return;
}
// 2. 마지막 클릭 시간 업데이트
lastClickTime.current = now;
const x = e.clientX;
const y = e.clientY;
// 3. 로그 객체 생성 (Worker 연산 요청 등 후속 작업 진행)
const newLog = {
event_id: crypto.randomUUID(),
click_coordinate: { x, y },
timestamp: new Date().toISOString(),
// ... 나머지 필드
};
setLogs((prev) => [...prev, newLog]);
// Web Worker에게 계산 요청 (이전 단계에서 만든 로직 호출)
// workerRef.current?.postMessage({ clickCoord: { x, y }, ... });
};
return (
<div
onClick={handleClick}
style={{ width: '100vw', height: '100vh', cursor: 'crosshair' }}
>
{/* 게임 화면 렌더링 */}
</div>
);
}3. 이 방식이 주는 이점
- ML 데이터 정제: 사용자가 당황해서 마구잡이로 누른 클릭 정보가 필터링 → 실제 의도가 담긴 클릭 위주로 데이터 수집
- 연산 부하 감소: Web Worker에게 계산을 시키는 빈도 자체가 감소 (최대 1초에 약 3회까지만 연산)
- 메모리 관리: 로그 배열 크기의 비정상적인 커짐을 물리적으로 방어
4. 추가 팁: UI 피드백
- 사용자가 클릭했는데 아무 반응이 없으면 "게임이 멈췄나?"라고 생각할 수 있다.
- 0.3초 이내의 클릭이라 로그는 남기지 않더라도, **시각적인 클릭 효과(예: 작은 물결 파동)**는 스로틀링 없이 즉시 보여줌이 UX 측면에서 훨씬 좋음
- 로그 수집 로직: 스로틀링 적용 (0.3초)
- 시각 효과 로직: 즉시 실행 (No Throttle)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels