Guides · 08
Performance and playback
How Animated avoids work each frame, how to check which path an element uses, and how the numbers on the home page were measured.
Three playback paths
Animated picks a path per property. The API does not change with the path.
| Path | When | Work per frame |
|---|---|---|
| browser | Finite transform and opacity motion on Animated.<tag> elements, including springs | None in the page's JavaScript |
| css | Exact curves the browser can express with shared CSS keyframes | None in the page's JavaScript |
| js | Ordinary style variables, input, custom computation and sequence boundaries | One write per value, no React render |
One value, many elements
Derivations of a hook value are calc() expressions. With scope, one variable write per frame drives every element in the container.
Preparing the example…
Check the path
inspect(element) returns the driver and fallback reason for each animated property during a real run.
import { inspect } from '@kkwaenggwari/animated';
console.table(inspect(element));
// property driver reason
// transform browser null
// opacity css null
// --level js css-variable-requires-jsStarts from the first frame
When the task that starts a motion keeps the main thread busy, such as hydration or a large commit, the motion restarts once that work ends instead of appearing already advanced. A start on a hidden page finishes in the background.
How the home page numbers were measured
Each scenario ran in a fresh page after one warm-up, three recorded samples, reporting the median. JavaScript time is the time spent inside animation-frame callbacks while the motion runs. It excludes style, layout and paint, which the browser does for every approach, so it is not a measure of total CPU or frame rate.
Browser playback does not make layout, paint, compositing or memory free. Measure the real screen on the devices you support.
| Scenario | Setup | Result |
|---|---|---|
| 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