Cursor나 Claude로 프론트엔드 코드를 생성하는 일이 일상이 된 지금, 아이러니하게도 브라우저 네이티브 API를 이해하는 능력이 더 중요해졌다. AI는 element.animate()를 순식간에 작성해 주지만, 그 코드가 왜 requestAnimationFrame보다 나은지, pushState 없이 SPA 라우팅이 왜 망가지는지, SpeechSynthesis.speak()가 사용자 제스처 없이 왜 침묵하는지는 직접 설명해 주지 않는다. 원리를 모르면 AI 출력물을 평가할 기준이 없고, 기준이 없으면 코드 리뷰는 패턴 매칭으로 전락한다.
모션: Web Animations API가 CSS 애니메이션을 대체하지 않는 이유
velog의 기술 포스트(@ehdgus8054/Web-Animations-API)가 잘 짚어냈듯, WAAPI(Web Animations API)는 CSS Animations와 CSS Transitions의 내부 작동 원리를 그대로 노출한 API다. @keyframes를 JavaScript 객체로 표현하고, 재생·일시정지·역방향 재생·타임라인 탐색 같은 플레이백 제어권을 개발자에게 돌려준다.
실무에서 핵심은 element.animate() 단축 메서드다. 키프레임 배열과 옵션 객체를 던지면 즉시 Animation 인스턴스가 반환되고, 브라우저가 내부 최적화를 알아서 처리한다—requestAnimationFrame 루프를 직접 작성할 필요도, 억지로 렌더링을 유발할 필요도 없다. 사용자의 스크롤 위치나 클릭 같은 동적 이벤트에 반응해 애니메이션을 즉각 조작해야 하는 인터랙티브 웹에서 이 API가 진가를 발휘하는 지점이다.
여기서 프로덕트 사고가 필요하다. AI에게 "스크롤 연동 애니메이션 만들어줘"라고 프롬프트를 던지면 GSAP나 Framer Motion 코드가 나올 수도 있고, WAAPI 코드가 나올 수도 있다. 어느 쪽이 더 적합한지 판단하려면 번들 사이즈, 브라우저 최적화 경로, 접근성(prefers-reduced-motion 미디어 쿼리와의 연동) 같은 맥락을 개발자가 직접 평가해야 한다. document.getAnimations()로 페이지 전체 애니메이션을 일괄 제어하는 패턴—예컨대 '애니메이션 줄이기' 접근성 옵션 구현—은 라이브러리가 추상화해 버린 영역이기도 하다.
내비게이션: History API가 없으면 SPA 라우터도 없다
React Router, Next.js App Router, TanStack Router—현대 프론트엔드 라우팅의 모든 마법은 결국 세 가지 브라우저 원시 API 위에서 작동한다. pushState(), replaceState(), 그리고 popstate 이벤트다. @ehdgus8054/History-API 포스트가 보여주는 예제는 단순하지만 핵심을 정확히 찌른다.
fetch()로 콘텐츠를 가져와 DOM을 갱신해도, pushState()로 세션 기록에 가상 항목을 추가하지 않으면 브라우저의 뒤로 가기 버튼은 SPA 내부 상태가 아니라 이전 도메인으로 사용자를 날려버린다. `pushState(result, "