FrameRateHelper is a lightweight, zero-dependency JavaScript library for detecting screen refresh rates (60Hz, 120Hz, 144Hz and higher) using requestAnimationFrame. It provides accurate frame timing and duration calculations for animations, rendering, and other refresh-rate-aware browser applications.
- π Detects screen refresh rate using requestAnimationFrame
- π₯οΈ Supports 60Hz, 90Hz, 120Hz, 144Hz, 165Hz and higher refresh rates
- π§ Falls back to requestIdleCallback or setTimeout when needed
- π§± Built-in clamping prevents duration spikes on slow devices or inactive tabs
- π Calculates frame duration and frame-based animation timing
- βοΈ Optional min/max duration limits and rounding controls
- πͺΆ Lightweight, zero-dependency, pure vanilla JavaScript
jsDelivr:
<!-- Development version (readable, unminified, includes source map) -->
<script src="https://cdn.jsdelivr.net/gh/InfinitumForm/FrameRateHelper@v1.0.2/dist/FrameRateHelper.js"></script>
<!-- Production version (minified, optimized for speed) -->
<script src="https://cdn.jsdelivr.net/gh/InfinitumForm/FrameRateHelper@v1.0.2/dist/FrameRateHelper.min.js"></script>unpkg:
<!-- Development version (readable, unminified, includes source map) -->
<script src="https://unpkg.com/framerate-helper@1.0.2/dist/FrameRateHelper.js"></script>
<!-- Production version (minified, optimized for speed) -->
<script src="https://unpkg.com/framerate-helper@1.0.2/dist/FrameRateHelper.min.js"></script>This exposes window.FrameRateHelper globally.
npm install framerate-helperThen in your module:
import FrameRateHelper from 'framerate-helper';const fps = new FrameRateHelper();
fps.onReady((hz) => {
console.log('Detected refresh rate:', hz.toFixed(2), 'Hz');
console.log('Estimated frame duration:', fps.getDuration(), 'ms');
});const duration = fps.getDuration(300); // base + 300ms offsetconst duration = fps.getDurationForFrames(90); // Duration for 90 framesconst duration = fps.getDurationForFrames(90, {
min: 1000, // minimum 1 second
max: 2000, // maximum 2 seconds
rounded: true // round to nearest integer
});const desiredFrames = 120;
let duration = fps.getDurationForFrames(desiredFrames, {
max: 2500, // prevent overly long animations
min: 800, // ensure minimum visibility
rounded: true
});
myElement.style.transitionDuration = `${duration}ms`;Creates a new instance and begins refresh rate measurement immediately.
Waits for refresh rate calculation to complete and then executes the callback.
callback (function): Receives detected refresh rate (Hz)
Returns an adjusted frame duration based on screen refresh rate.
offset (number): Optional duration to add (in ms)- Returns: total duration in ms
Calculates duration based on number of frames.
frames (number): Desired number of animation framesoptions (object)(optional):min (number): Minimum allowed duration in msmax (number): Maximum allowed duration in msrounded (boolean): Iftrue, rounds result
- Returns: clamped, optionally rounded duration in ms
You can seamlessly use FrameRateHelper (for example) with jQuery animation methods to ensure frame-synced transitions:
const fps = new FrameRateHelper();
fps.onReady(() => {
const duration = fps.getDuration(400); // add a 400ms offset if desired
// Smoothly toggle element visibility with frame-accurate duration
$('.my-element').slideToggle(duration);
// Show/hide with consistent frame-based speed
$('.other-element').show(duration);
$('.another-one').hide(duration);
});FrameRateHelper is especially useful when animations need to behave consistently across displays with different refresh rates, including 60Hz, 120Hz, 144Hz and higher.
- Precision timing for sliders, carousels and UI transitions
- Frame-based motion control for games and interactive interfaces
- Refresh-rate-aware scroll, fade and transition effects
- Frame timing for Canvas and WebGL rendering
- Consistent animation behavior across standard and high-refresh-rate displays
MIT License β free for personal and commercial use.
Author: Ivijan-Stefan StipiΔ
Β© 2025 Ivijan-Stefan StipiΔ. All rights reserved.
For issues, contributions, or improvements, please visit the GitHub repository.
Happy animating! π¨