Skip to main content

useFps

Description and use case

useFps measures frame deltas with requestAnimationFrame and exposes a rolling FPS average. Use it to disable expensive animations, canvas effects, video backgrounds, or other non-essential UI when the browser falls below your target frame rate.

API signature

function useFps(options?: UseFpsOptions): UseFpsReturn;

Parameters

NameTypeRequiredDescription
options.thresholdnumberNoFPS threshold used to set isLowPerformance. Defaults to 30.
options.windowSizenumberNoNumber of recent frame deltas used for the moving average. Defaults to 10.
options.onDrop(currentFps: number) => voidNoCallback fired when the rolling average crosses below threshold.
options.enabledbooleanNoSet false to disable the rAF loop.

Return value

FieldTypeDescription
fpsnumberRolling-averaged FPS. Returns 0 until the first measured frame.
isLowPerformancebooleanWhether fps is below the configured threshold.
isSupportedbooleanWhether this browser supports requestAnimationFrame and cancelAnimationFrame.

Live interactive demo (StackBlitz)

GitHub Pages does not serve the isolation headers required for embedded StackBlitz WebContainers. Open the demo in StackBlitz to run it interactively.

Code example

import { useFps } from 'react-perf-hooks';

export function AdaptiveMedia() {
const { fps, isLowPerformance, isSupported } = useFps({
threshold: 30,
windowSize: 10,
onDrop: (currentFps) => {
navigator.sendBeacon('/analytics/fps-drop', JSON.stringify({ currentFps }));
},
});

if (!isSupported) {
return <StaticImage />;
}

return (
<section>
<p>FPS: {fps.toFixed(0)}</p>
{isLowPerformance ? <StaticImage /> : <HeavyLottieAnimation />}
</section>
);
}

Notes

  • onDrop fires on transitions into low-performance mode, not on every low-FPS frame.
  • Background-tab rAF pauses are excluded from the rolling average.
  • The hook cancels the active animation frame loop when the component unmounts.