가이드 · 08
성능과 재생 경로 Animated가 프레임마다 일을 줄이는 방식, 요소가 어떤 경로를 쓰는지 확인하는 법, 홈의 수치를 측정한 방법.
세 가지 재생 경로 Animated는 속성마다 경로를 고릅니다. 경로가 달라져도 API는 같습니다.
경로 언제 프레임당 작업 browser Animated.<tag> 요소의 유한한 transform·opacity 모션(스프링 포함)페이지 JavaScript 없음 css 브라우저가 공유 CSS 키프레임으로 표현할 수 있는 정확한 곡선 페이지 JavaScript 없음 js 평범한 style 변수, 입력, 사용자 계산, 시퀀스 경계 값마다 쓰기 한 번, React 렌더 없음
값 하나, 많은 요소 훅 값의 파생은 calc() 식입니다. scope를 쓰면 프레임마다 변수 쓰기 한 번이 컨테이너의 모든 요소를 움직입니다.
JavaScript가 꺼져 있습니다. 아래 코드가 예제의 전체 소스입니다.
App.jsx import { useRef } from 'react' ;
import { Easing , loop, timing, useAnimated } from '@kkwaenggwari/animated' ;
import './styles.css' ;
export default function App ({ count = 1600 , amplitude = 16 , duration = 2400 } ) {
const field = useRef (null );
const renders = useRef (0 );
renders.current += 1 ;
const wave = useAnimated (
0 ,
(value ) => {
loop (timing (value, { toValue : 1 , duration, easing : Easing .linear }));
},
[duration],
{ scope : field },
);
const columns = Math .ceil (Math .sqrt (count * 2.8 ));
const dots = Array .from ({ length : count }, (_, index ) => index);
return (
<div className ="stage" >
<div className ="meta" >
<span > {count.toLocaleString('en-US')} dots</span >
<span > React renders: {renders.current}</span >
</div >
<div className ="field" ref ={field} style ={{ gridTemplateColumns: `repeat (${columns }, 1fr )` }}>
{dots.map((index) => {
const phase = (index % columns) / columns + Math.floor(index / columns) / 18;
return (
<i
key ={index}
style ={{
transform: `translateY (calc (sin ((${wave } + ${phase }) * 1turn ) * ${amplitude }px ))`,
opacity: `calc (0.55 + cos ((${wave } + ${phase }) * 1turn ) * 0.45 )`,
}}
/>
);
})}
</div >
</div >
);
}styles.css .stage {
display : grid;
gap : 16px ;
padding : 24px ;
}
.meta {
display : flex;
flex-wrap : wrap;
justify-content : space-between;
gap : 8px ;
font :
600 14px /1.4 ui-monospace,
SFMono-Regular,
Consolas,
monospace;
color : #1a33c7 ;
}
.field {
display : grid;
grid-auto-rows : 1 fr;
gap : 2px ;
height : 280px ;
padding : 28px 16px ;
border-radius : 16px ;
background : #0b1440 ;
overflow : hidden;
}
.field i {
display : block;
width : 100% ;
max-width : 8px ;
aspect-ratio : 1 ;
align-self : center;
justify-self : center;
border-radius : 50% ;
background : #5c7cff ;
}
.field i :nth-child (3 n) {
background : #8fb0ff ;
}
.field i :nth-child (7 n) {
background : #ffffff ;
}경로 확인하기 inspect(element)는 실제 실행 중에 움직이는 속성마다 드라이버와 대체 이유를 돌려줍니다.
debug.js 복사 import { inspect } from '@kkwaenggwari/animated' ;
console .table (inspect (element));
첫 프레임부터 시작 모션을 시작한 작업이 하이드레이션이나 큰 커밋처럼 메인 스레드를 오래 붙잡으면, 이미 진행된 것처럼 보이는 대신 그 작업이 끝난 뒤 처음부터 다시 시작합니다. 숨겨진 페이지에서 시작한 모션은 백그라운드에서 끝납니다.
홈 수치를 측정한 방법 각 시나리오는 새 페이지에서 워밍업 한 번 뒤 세 번 기록하고 중앙값을 보고했습니다. JavaScript 시간은 모션이 도는 동안 애니메이션 프레임 콜백 안에서 쓴 시간입니다. 모든 방식에서 브라우저가 하는 style·레이아웃·페인트는 제외하므로 전체 CPU나 프레임률을 뜻하지 않습니다.
브라우저 재생이 레이아웃, 페인트, 합성, 메모리를 공짜로 만들지는 않습니다. 지원하는 기기의 실제 화면에서 측정하세요.
시나리오 구성 결과 400 Animated.div elements move translateX and fade in (timing, 1800 ms) seed/pose/tempo on Animated.div; 800 browser animations 0.00 ms One useAnimated value drives 10,000 elements in ordinary style (loop, 1200 ms) transform and opacity as calc() of one CSS variable written on a scope element 0.13 ms
2026-09-28 · Chrome 153.0.8010.52 (headless) · Windows_NT x64 · Intel(R) Core(TM) i7-14700K