requestAnimationFrame: UI 레이아웃 썸 해결책
AI Store에서 AI코딩으로 만들어진 앱을 만나보세요!
지금 바로 방문하기

requestAnimationFrame: UI 레이그ущ의 해결책

카테고리

프로그래밍/소프트웨어 개발

서브카테고리

웹 개발

대상자

  • *프론트엔드 개발자, 애니메이션 및 UI/UX 개발자**
  • 난이도: 중간 (기본적인 JavaScript 지식 필요)

핵심 요약

  • requestAnimationFrame()는 브라우저의 60fps 렌더링 주기와 동기화되어 animations, DOM 업데이트를 정확히 수행하는 데 사용됨
  • setTimeout(fn, 16)렌더링 주기와 비동기로 실행되어 프레임 떨림레이아웃 썸(layout thrash) 발생 가능
  • 고주파 디스플레이(예: 120Hz)에서는 프레임 예산이 8ms로 줄어들며, requestAnimationFrame()은 자동으로 조정됨

섹션별 세부 요약

1. 브라우저의 렌더링 주기 이해

  • 브라우저는 60fps(약 16.66ms/프레임)로 화면을 업데이트
  • 프레임 처리 순서: 입력 처리 → JavaScript 실행 → 스타일 적용 → 레이아웃/페인트
  • 시간 초과프레임 드롭, 애니메이션 부드러움 저하, UI 레이그ущ 발생

2. `requestAnimationFrame()`의 장점

  • 렌더링 직전에 콜백 실행 → DOM 업데이트 및 스타일 조정 가능
  • timestamp 파라미터performance.now()와 동일한 고해상도 시간 제공
  • requestAnimationFrame()렌더링 루프(render loop)의 일부로, 애니메이션, 배치 DOM 업데이트, 스크롤 위치 추적에 적합

3. React에서의 적용 예시

  • 스크롤 기반 상태 업데이트: useEffectrequestAnimationFrame을 결합해 프레임 레이트 기반 타rottle
  • useEffect(() => {
      let animationFrameId;
      const handleScroll = () => {
        if (animationFrameId) return;
        animationFrameId = requestAnimationFrame(() => {
          const scrollTop = window.scrollY;
          setScrollPosition(scrollTop);
          animationFrameId = null;
        });
      };
      window.addEventListener('scroll', handleScroll);
      return () => {
        window.removeEventListener('scroll', handleScroll);
        if (animationFrameId) cancelAnimationFrame(animationFrameId);
      };
    }, []);
  • CSS 클래스 적용 시: 레이아웃 안정 후 시각적 상태 업데이트
  • useEffect(() => {
      const id = requestAnimationFrame(() => setShowTooltip(true));
      return () => cancelAnimationFrame(id);
    }, [hovered]);

4. `requestAnimationFrame()`과 `setTimeout()`의 조합

  • 배경 탭에서의 대체: document.hidden을 체크해 setTimeout으로 대체
  • function loop() {
      if (document.hidden) {
        setTimeout(loop, 100);
      } else {
        requestAnimationFrame(loop);
      }
    }
  • 간헐적 애니메이션: setTimeout 내부에 requestAnimationFrame 사용
  • setTimeout(() => {
      requestAnimationFrame(runAnimation);
    }, 250);

5. 주의사항 및 피해야 할 패턴

  • 피드백 루프(feedback loop) 생성 시 애니메이션 의도가 흐려짐
  • requestAnimationFrame()React 렌더링을 중단하지 않음useRef와 함께 사용해 과도한 렌더링 방지
  • 고주파 디스플레이에서 대량의 상태 업데이트성능 저하 유발 가능

결론

  • requestAnimationFrame()브라우저 렌더링 주기와 동기화하여 부드러운 UI저지연을 달성하는 핵심 도구
  • setTimeout(fn, 16)보다 렌더링 주기 기반으로 프레임 드롭 방지
  • React에서 상태 기반 애니메이션, 스크롤 처리, DOM 배치에 반드시 사용하며, useRef와 조합해 성능 최적화
  • 고주파 디스플레이 사용 시 프레임 예산 조정배경 탭 대체 로직(setTimeout) 적용 필수