Skip to content

Chore: 스로틀링 vs 디바운스 - 광클 방지, 무엇이 더 적합할까? #2

@elian118

Description

@elian118

무분별한 클릭(광클)은 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions