Description
About Camera FPS Test
Introduction
The DeviceHub Camera FPS Test estimates how many frames per second your live webcam preview is actually delivering inside the browser, separate from the frame rate printed on a product box or assumed by meeting software defaults. Sticker rates like 60 FPS describe hardware potential under ideal conditions; web applications often receive something lower after negotiation, USB bandwidth contention, thermal throttling, background tab scheduling, and compositor load on the main thread. This free tool opens a camera stream with getUserMedia and samples rendered frame timing, primarily through HTMLVideoElement.requestVideoFrameCallback when the browser supports it, to produce a practical FPS estimate for troubleshooting choppy meetings, soft motion in local recordings, and sluggish self-view during presentations. Gamers evaluating a capture path before streaming, remote presenters diagnosing stutter that looks like network issues, and engineers comparing browsers on identical hardware gain a motion metric that resolution tests alone cannot provide. Because requestVideoFrameCallback fires near presentation time, the measurement reflects what you see rather than what a driver claims in a static settings panel. Treat sustained averages over several seconds as more trustworthy than a single-frame spike during the first second of auto-exposure hunting.
What this tool does
After camera permission is granted, the page attaches a video MediaStreamTrack to a preview element and measures how frequently new frames arrive for display during a sustained sampling window. It may also show the frameRate value from MediaStreamTrack.getSettings() as a negotiated hint from the capture pipeline, while the live estimate reflects what the page observes through timing callbacks during active sampling. You can switch cameras to compare built-in laptop sensors versus external USB webcams under the same CPU load. The test emphasizes sustained delivery over several seconds rather than a single instantaneous spike that might mislead you during auto-exposure adjustments. Stopping ends the MediaStream and cancels pending frame callbacks. Use the result to judge whether motion looks closer to 15 FPS with noticeable stepping, roughly 30 FPS typical for standard calls, or higher on capable devices with adequate USB bandwidth and foreground tab priority. The UI may note when requestVideoFrameCallback is unavailable so you know fallback counters are less precise than frame-presented callbacks on supported Chromium builds.
When to use it
Use the FPS test when video looks stuttery despite acceptable resolution readings, when evaluating a new webcam for game streaming or tutorial recording, when comparing Chrome and Firefox performance on identical hardware, or when a laptop thermal-throttles during long calls and motion degrades over time. Run it after moving a camera to a different USB port or through a powered hub, and before blaming network bandwidth for choppiness that may actually originate in local capture or main-thread congestion. Pair with the latency test when the primary complaint is lip-sync delay rather than frame drops, and with the resolution test when you suspect the browser traded frame rate for larger frame dimensions during negotiation. Keep the tab foregrounded because background throttling dramatically skews results. Educators recording screencasts with a picture-in-picture webcam overlay also use FPS sampling to catch stutter before publishing LMS content. Broadcast engineers validating capture chains before live events rely on sustained FPS averages rather than sticker claims on retail packaging.
How it works
The page calls navigator.mediaDevices.getUserMedia for a video track and binds the resulting MediaStream to an HTMLVideoElement configured for inline playback without unnecessary audio capture. Where available, HTMLVideoElement.requestVideoFrameCallback schedules a callback for each composited frame presented to the user; timestamps between consecutive callbacks yield an instantaneous rate that is averaged over a configurable sampling window for stability and readability on the results panel. Fallback paths may count frames using performance.now() around drawImage canvas sampling or timeupdate events when requestVideoFrameCallback is missing, with lower precision acknowledged transparently in the UI copy. MediaStreamTrack.getSettings().frameRate reports the constrained or negotiated rate the browser believes is active, useful context, but not identical to delivered composition rate under CPU load or tab throttling policies. Background tab scheduler limits, operating-system power-saver modes, and heavy main-thread JavaScript from unrelated extensions can all reduce measured FPS without changing the camera's theoretical hardware capability. HTTPS secure context is required for capture, and permission must be granted before meaningful sampling begins on the live preview element. Pairing requestVideoFrameCallback timestamps with getSettings().frameRate helps distinguish negotiation hints from compositor-limited delivery under load.
Step-by-step instructions
- Open the Camera FPS Test on a machine with minimal background CPU load and keep the browser tab fully visible in the foreground, because hidden tabs often receive throttled timers that artificially lower measured frame delivery rates.
- Click Start and allow camera permission when prompted so getUserMedia can open an active video track suitable for requestVideoFrameCallback sampling or an equivalent fallback frame counter tied to the preview element.
- Wait at least five to ten seconds while the estimator collects frame timing samples across multiple callback intervals so the displayed average stabilizes instead of jumping wildly on the first frame after exposure settles.
- Compare the measured FPS readout against any negotiated frameRate value shown from MediaStreamTrack.getSettings(), noting when settings claim 30 but measurement shows materially lower delivery indicative of throttling or load.
- Optionally switch cameras, USB ports, or browsers and re-run the test under the same foreground conditions to build a relative performance table you can attach to support documentation or bug reports.
- Click Stop when finished measuring so all MediaStreamTracks end through track.stop(), pending requestVideoFrameCallback loops cancel, and the camera becomes available for other applications without requiring a browser restart.
Common problems
Low readings in a background tab are usually scheduler throttling rather than a broken camera sensor, so always retest with the tab focused before replacing hardware. Autofocus hunting and aggressive auto-exposure adjustments can introduce visible hitching that looks like dropped frames even when the callback rate stays steady. USB 2.0 hubs shared with storage devices may starve high frame-rate modes for 1080p webcams simultaneously. Virtual camera software and OS-level background blur can cap FPS globally across all applications until disabled. If getSettings().frameRate claims 30 FPS but measurement hovers near 15, investigate CPU load, browser energy saver toggles, overlapping capture in conferencing apps, and thermal limits before assuming driver failure. Variable lighting that triggers repeated exposure recalculation can also depress short-window averages until the scene stabilizes. Document browser name, tab focus state, and sampling duration when comparing runs across days. Document browser name, tab focus, and sampling duration when attaching FPS results to support tickets for reproducibility. If meeting apps feel smooth but this page measures low FPS, compare whether those apps use hardware-accelerated capture paths not exposed to generic getUserMedia preview elements.
Privacy explanation
Frame timing statistics are computed entirely locally from your preview pipeline using browser APIs such as requestVideoFrameCallback and performance.now(); no video frames or FPS logs are uploaded to DeviceHub servers or third-party analytics endpoints. Camera permission is used only to open the diagnostic MediaStream for the duration of your active session on this page. Stop the test to end capture immediately and extinguish the hardware indicator light when your browser supports that signaling after tracks stop. Clear site permissions whenever you want to remove grant for this origin without affecting unrelated websites. Historical FPS averages are not persisted in cloud storage or shared with analytics partners after you close the tab. Measured FPS values exist only in your tab memory during the test and are not serialized to localStorage or sent to analytics endpoints when sampling completes.