Skip to main content
The PerformanceMetrics component provides real-time performance monitoring to help developers optimize their animations for smooth 60 FPS playback.

Features

FPS tracking

Real-time frames per second measurement

Statistics

Current, average, min, and max FPS values

Visual indicators

Color-coded performance status (green/yellow/red)

History tracking

Maintains rolling average over last 60 samples

Implementation

The component uses requestAnimationFrame to measure rendering performance:
function FPSStats() {
  const [fps, setFps] = useState(0)
  const [avgFps, setAvgFps] = useState(0)
  const [minFps, setMinFps] = useState(Infinity)
  const [maxFps, setMaxFps] = useState(0)
  const frameRef = useRef<number>(0)
  const lastTimeRef = useRef<number>(performance.now())
  const fpsHistoryRef = useRef<number[]>([])

  useEffect(() => {
    const measureFPS = (timestamp: number) => {
      frameRef.current++
      const elapsed = timestamp - lastTimeRef.current

      if (elapsed >= 1000) {
        const currentFps = Math.round((frameRef.current * 1000) / elapsed)
        setFps(currentFps)

        fpsHistoryRef.current.push(currentFps)
        if (fpsHistoryRef.current.length > 60) {
          fpsHistoryRef.current.shift()
        }

        const avg = Math.round(
          fpsHistoryRef.current.reduce((a, b) => a + b, 0) /
            fpsHistoryRef.current.length
        )
        setAvgFps(avg)
        setMinFps(Math.min(currentFps, minFps))
        setMaxFps(Math.max(currentFps, maxFps))

        frameRef.current = 0
        lastTimeRef.current = timestamp
      }

      requestAnimationFrame(measureFPS)
    }

    requestAnimationFrame(measureFPS)
  }, [minFps, maxFps])

  // ... render logic
}

Performance indicators

The component uses color-coded indicators:
  • Green (55+ FPS) - Excellent performance, smooth animations
  • Yellow (50-54 FPS) - Minor stutters, generally acceptable
  • Red (Below 50 FPS) - Noticeable lag, optimization needed

FPS calculation

const currentFps = Math.round((frameRef.current * 1000) / elapsed)
This formula calculates FPS by:
  1. Counting frames rendered in the last second
  2. Dividing by the actual elapsed time
  3. Multiplying by 1000 to get frames per second

Metrics displayed

Shows the FPS from the most recent measurement interval. Updates every second.

Using the component

import PerformanceMetrics from './components/PerformanceMetrics'

<section>
  <h2>Performance Monitoring</h2>
  <PerformanceMetrics />
</section>

Optimization tips

If you see low FPS:
1

Use transform and opacity

These properties are GPU-accelerated and don’t trigger layout or paint.
2

Avoid layout properties

Properties like width, height, top, left force expensive layout recalculations.
3

Add will-change

Tell the browser which properties will animate: will-change: transform, opacity
4

Reduce animation count

Too many simultaneous animations can overwhelm the GPU.
Don’t leave will-change on elements permanently - it consumes memory. Add it just before animating and remove it after.

Build docs developers (and LLMs) love