Tan Kim

patterns

UI 패턴

UX 동작 및 성능 최적화 관련 기법 모음.

Debounce

연속된 이벤트 중 마지막 호출만 실행. 입력이 멈춘 뒤 일정 시간 후 실행된다.

입력: A--B--C-----------D
실행:                   C              D
                    (delay 후)     (delay 후)

사용 예시: 검색 자동완성, 폼 유효성 검사

function debounce<T extends (...args: any[]) => void>(fn: T, delay: number) {
  let timer: ReturnType<typeof setTimeout>;
  return (...args: Parameters<T>) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}
 
const onSearch = debounce((value: string) => {
  fetchResults(value);
}, 300);

Throttle

연속된 이벤트를 일정 간격마다 한 번씩만 실행. 실행 횟수를 제한한다.

입력: A--B--C--D--E--F--G
실행: A-----------D-----------G
         (interval)  (interval)

사용 예시: 스크롤 이벤트, 리사이즈 이벤트, 버튼 연속 클릭 방지

function throttle<T extends (...args: any[]) => void>(fn: T, interval: number) {
  let lastTime = 0;
  return (...args: Parameters<T>) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn(...args);
    }
  };
}
 
const onScroll = throttle(() => {
  updateScrollPosition();
}, 100);

Debounce vs Throttle

Debounce Throttle
실행 시점 입력 멈춘 후 일정 간격마다
중간 이벤트 모두 무시 일부 실행
적합한 상황 최종 값만 필요 중간 상태도 필요
예시 검색창 입력 스크롤, 리사이즈

Scroll

스크롤 이벤트 기본

window.addEventListener('scroll', throttle(() => {
  const scrollY = window.scrollY;
  const totalHeight = document.body.scrollHeight - window.innerHeight;
  const progress = scrollY / totalHeight; // 0 ~ 1
}, 100));

무한 스크롤

window.addEventListener('scroll', throttle(() => {
  const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
  if (scrollTop + clientHeight >= scrollHeight - 200) {
    loadMore();
  }
}, 200));

Intersection Observer (권장)

스크롤 이벤트 대신 요소의 뷰포트 진입 여부를 감지. 성능상 유리.

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      loadMore();
    }
  });
}, { threshold: 0.1 });
 
observer.observe(document.querySelector('#sentinel')!);
방식 성능 정밀도 용도
scroll 이벤트 낮음 (throttle 필요) 높음 스크롤 위치 기반 로직
IntersectionObserver 높음 중간 요소 노출 감지, 무한 스크롤, lazy load

메모