Skip to content

Instantly share code, notes, and snippets.

@PeteTheHeat
Last active March 13, 2024 19:36
Show Gist options
  • Save PeteTheHeat/aa10eb8c13413317bb16cdec10325e8f to your computer and use it in GitHub Desktop.
Save PeteTheHeat/aa10eb8c13413317bb16cdec10325e8f to your computer and use it in GitHub Desktop.
import React, { useEffect, useRef, useState } from 'react'
/*
A simple FPS meter that displays the average FPS over the last 10 frames.
The FPS meter only updates when the average FPS changes by 10 or more to avoid flickering.
*/
const FPSMeter: React.FC = () => {
const [fps, setFps] = useState<number>(0)
// Buffer to store the last 10 FPS values.
const fpsBufferRef = useRef<number[]>([])
const lastFrameTimeRef = useRef<number>(performance.now())
useEffect(() => {
let animationFrameId: number
// A function to update the FPS every frame, called recursively using requestAnimationFrame.
const updateFPS = () => {
const currentTime = performance.now()
const deltaTime = currentTime - lastFrameTimeRef.current
const newFps = Math.round(1000 / deltaTime)
// newFPS can occasionally be very large (ie: 1000+) due to fluctuations in performance.now().
// Cap it at 120 to avoid FPS spikes.
if (newFps <= 120) {
fpsBufferRef.current.push(newFps)
if (fpsBufferRef.current.length > 10) {
fpsBufferRef.current.shift()
}
const averageFps = Math.round(
fpsBufferRef.current.reduce((acc, val) => acc + val, 0) / fpsBufferRef.current.length,
)
setFps((prevFps) => {
if (Math.abs(averageFps - prevFps) >= 10) {
return averageFps
}
return prevFps
})
lastFrameTimeRef.current = currentTime
}
animationFrameId = requestAnimationFrame(updateFPS)
}
animationFrameId = requestAnimationFrame(updateFPS)
return () => {
// When the component is unmounted, cancel the animation frame to avoid a memory leak.
cancelAnimationFrame(animationFrameId)
}
}, []) // Empty dependency array to run effect only once on mount.
return <div>FPS: {fps}</div>
}
export default FPSMeter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment