Frame Sampling and Warm-Up
Frame-related tools use window.requestAnimationFrame() and the callback timestamp supplied by the browser. Consecutive timestamps are subtracted to create raw frame intervals in milliseconds. The page does not count callback invocations inside a one-second bucket and then label that integer as the only result; interval sampling preserves timing distribution and supports mathematically consistent statistics.
Each new run begins with a 1.2-second warm-up. Callbacks during warm-up are not included in reported results. Initialization, canvas allocation, code compilation, and the first scheduling transition can otherwise distort a short sample. Starting again after stopping or hiding the page performs a fresh warm-up and begins a new result set.
Visibility and Valid Sample Filtering
Browsers reduce or stop animation callbacks for hidden documents. FPS Tester listens for visibilitychange and stops an active FPS-series test as soon as the document becomes hidden. The page does not insert the time spent in another tab as an FPS drop or timing spike. The user starts a new run, which performs another warm-up before valid collection continues.
Statistical functions accept only finite intervals greater than zero. The live sampler also rejects intervals at or above one second as invalid for ordinary frame statistics. That upper guard is separate from hidden-tab handling and prevents an extraordinary suspension from dominating arrays. It is not used to erase ordinary slow frames: intervals below one second remain eligible for tail and spike analysis.
One-Second Chart and Stress Workload
FPS-series charts group valid frame intervals into approximately one-second buckets. FPS views plot three connected series for each elapsed second: average FPS uses 1000 / mean bucket interval, minimum FPS uses the longest interval, and maximum FPS uses the shortest interval. Frame-time views plot the mean interval in milliseconds. Detailed result cards continue to use the complete retained interval sample.
Stress Level controls a local canvas workload from zero to 1,400 animated elements. The animation appears only during an active test and changes immediately when the slider moves. It is intended to create a repeatable browser-side rendering condition for comparison; it is not a native GPU benchmark, a hardware rating, or a substitute for application-specific profiling.
Average, Median, Variance, and Percentiles
Mean frame time is the arithmetic mean of valid millisecond intervals. Average FPS is 1000 / mean frame time; FPS Tester does not average rounded instantaneous FPS values. Median uses the center of a numerically sorted set, averaging the two central values for an even-sized set. Minimum and maximum frame time come directly from valid samples, while equivalent minimum FPS uses the longest interval and maximum FPS uses the shortest.
Variance is the population mean of squared differences from mean interval, and standard deviation is its square root. The coefficient of variation is standard deviation divided by mean interval, expressed as a percentage. Percentiles use linear interpolation at (n − 1) × q in the sorted set. P95, P99, and—when at least 1,000 intervals exist—P99.9 describe the slow side because larger frame time is worse.
FPS, Frames, and Duration Calculator
The FPS calculator uses FPS = total frames / duration in seconds, total frames = FPS × duration in seconds, and duration in seconds = total frames / FPS. Milliseconds multiply by 0.001, minutes multiply by 60, and hours multiply by 3,600 before calculation. Duration results divide the normalized seconds by the corresponding factor when another display unit is selected. Production rejects empty, non-finite, zero, negative, and overflowing inputs.
The calculator retains JavaScript numeric precision and rounds only for display. Ordinary values show up to six fractional digits; values below 0.000001 or at least one trillion use scientific notation to avoid layout-breaking strings. Frame-time context uses 1000 / FPS, but the calculator’s primary purpose remains the three-way relationship among rate, total frames, and total duration. It does not measure or predict application performance.
1% Low and 0.1% Low FPS
For 1% low, valid frame intervals are sorted from longest to shortest. The tool takes ceil(n × 0.01) intervals, calculates their mean, and converts that mean to equivalent FPS. At least 100 intervals are required. For 0.1% low, the fraction is 0.001 and at least 1,000 intervals are required. Until those thresholds are met, the interface states that samples are insufficient.
This definition is consistent throughout FPS Tester but is not the only convention used by native benchmark tools. Some software averages instantaneous FPS, uses a percentile cutoff, or processes presentation events differently. Comparisons must use the same method and source. Browser-observed lows cannot be substituted for a game’s own capture because this page has no access to that process.
Jitter, Stability Score, and Timing Spikes
Jitter is median absolute deviation: calculate the median interval, find each interval’s absolute distance from it, then take the median of those distances. The stability score is 100 × exp(-8 × relative MAD), clamped to 0–100, where relative MAD is jitter divided by median interval. This makes the score sensitive to consistency rather than absolute rate. Stable 60 FPS is not penalized solely for being slower than stable 144 FPS.
A timing spike is any valid interval above both median × 1.5 and median + 4 ms, once at least ten intervals exist. The threshold uses a robust median baseline plus an absolute guard for high-refresh noise. The label is intentionally “timing spike,” “slow frame,” or “irregular interval.” A callback gap is not conclusive proof that a physical presentation was dropped.
The frame pacing test also reports the share of intervals within ±10 percent of the median. Its alternation heuristic ignores deviations smaller than the greater of 0.5 ms or 5 percent, then measures how often meaningful above-median and below-median signs switch. At least six meaningful deviations are required. “Possible” and “strong pattern” describe this session’s cadence shape; they do not diagnose a fault.
Refresh Cadence Estimation
Refresh-rate estimation requires at least 120 valid frame intervals. The sorted set is trimmed by ten percent at both ends, the median remaining interval is converted to hertz, and the result is compared with a maintained list of common standards. Fractional 59.94 is listed separately from 60; a cadence near 119.88 will normally match 120 within the expected tolerance.
The refresh chart plots instantaneous browser callback hertz against a labeled five-second time axis, while the large translucent value shows the latest rate. The Refresh rate result remains the robust trimmed estimate rather than one instantaneous point. Confidence describes relative distance to the nearest standard: at most 0.8 percent is high, at most 2.5 percent is medium, and a larger difference is low. It does not certify hardware. Browser scheduling, multiple monitors, dynamic or variable refresh, power management, recording, and system load can make callback cadence disagree with the configured or physical rate.
Mouse Event and Reaction Timing
The mouse polling tool starts sampling when a non-touch pointer enters or moves inside its test area, pauses active elapsed time when the pointer leaves, and resumes the same sample set on re-entry until its in-stage Reset is used. It stores timestamps from pointer movement and uses coalesced sub-events when the browser supplies them. Positive intervals below 250 ms are converted to event rates. Estimated rate is the reciprocal of median event interval; average rate is the mean of individual reciprocals, and peak is the maximum. At most 5,000 timestamps are retained. These are browser-received events, not direct USB controller reports.
The reaction tool waits a random 1.4–4 seconds, applies the visible ready state, stores performance.now(), and ends on pointer or keyboard activation. Early input is a false start and is excluded. Five valid rounds report arithmetic mean, median, minimum, and population standard deviation. The measurement includes display, browser, input device, operating system, and human response.
Monitor Test Pattern Generation
The monitor test draws every pattern locally on a canvas whose backing store follows the rendered size at up to two times device pixel ratio. The suite includes four grayscale/RGB gradient bands, a striped visual gamma comparison, eighteen-step near-black and near-white patches, a continuous ramp plus hard contrast divisions, high-frequency sharpness lines, 5/25/50/75/100 percent uniformity fields, checkerboard geometry, a grid with circle and square guides, and generic RGB/CMY-style bars with a grayscale strip.
These patterns are visual diagnostic aids. The gamma labels are estimates, uniformity is judged by the viewer, and no part of the suite accesses a colorimeter, spectrophotometer, photodiode, EDID measurement, or panel controller. It cannot calculate Delta E, gamut, luminance, contrast ratio, pixel response, or calibration conformance. Fullscreen and hidden controls only reduce page distractions; they do not bypass browser, operating-system, GPU, or display processing.
Screen Bleeding Fields
The screen bleeding test renders six local solid fields: pure black #000000, approximately 5 percent gray #0d0d0d, approximately 10 percent gray #1a1a1a, and restrained dark blue, red, and green fields. The canvas is resized for the active display and fullscreen state. No camera, ambient-light sensor, image upload, or automatic pixel analysis is used. The viewer inspects edges, corners, and broad uniformity directly.
Interpretation is explicitly visual. Classic backlight bleed applies to LCD backlights; IPS glow changes with angle, clouding or mura is broader, and OLED has no LCD backlight. Brightness, local dimming, viewing angle, room light, panel temperature, picture mode, and camera exposure affect what appears. FPS Tester applies no universal defect threshold and does not infer a warranty outcome.
Color Banding Gradient Generation
The color banding test generates grayscale, red, green, blue, combined RGB, and dark gradients locally on canvas. Smooth mode asks the browser canvas implementation to interpolate across the full horizontal or vertical backing-store extent. Stepped modes draw exactly 256, 128, 64, or 32 equal segments, with the channel code derived from segment position. Combined RGB divides the orthogonal axis into three channel bands.
Canvas width and height track the CSS size multiplied by device pixel ratio capped at two, and patterns redraw after resize or fullscreen changes. That avoids an unnecessarily low-resolution backing store without creating unbounded canvases. It cannot establish native panel depth, GPU output depth, HDR precision, gamut, or defect status because browser rasterization, OS color management, GPU conversion, display processing, panel depth, dithering, compression, and HDR/SDR mapping remain in the visible path.
PPI, Pitch, Dimensions, and PPD Formulas
PPI uses pixelDiagonal = sqrt(widthPx² + heightPx²) and ppi = pixelDiagonal / diagonalInches. A centimeter diagonal is divided by 2.54. Pixels per centimeter is ppi / 2.54; pixel pitch is 25.4 / ppi millimeters; physical width and height are the corresponding pixel counts divided by PPI. Total pixels is width times height, megapixels divides that product by one million, and aspect ratio divides both whole-pixel dimensions by their greatest common divisor.
When viewing distance is provided, it is converted to inches and the linear width of one visual degree is 2 × distanceInches × tan(0.5 × π / 180). Pixels per degree multiplies that width by PPI. Production rejects zero, negative, non-finite, fractional-resolution, and malformed values. The flat-screen geometry does not model curved panels, lenses, off-axis regions, non-square pixels, unusual subpixel layouts, or incorrect user-supplied measurements.
Browser Mouse Event Delay Method
The mouse latency tool begins automatically when a non-touch pointer enters or moves inside its stage, pauses active elapsed time on pointer exit, and continues the same bounded session on re-entry until Reset is used. It listens to pointermove, reads getCoalescedEvents() where available, and stores event timestamp, handler performance.now(), and performance.timeOrigin for at most 5,000 samples. Epoch-sized event timestamps are normalized by subtracting time origin; relative timestamps are used directly. Non-finite data, negative timestamps, timestamps implausibly ahead of handler time, negative delays, origin mismatches, and delays over ten seconds are rejected from processing-delay statistics.
Validated delay is handler time minus normalized event time. Results use arithmetic mean, median, linearly interpolated P95, and population standard deviation for timing jitter. Positive consecutive event-timestamp differences below one second produce average event interval. If fewer than 80 percent of current samples yield validated delay, the interface marks processing delay unreliable and directs the user to interval and sample statistics. Coalesced events describe browser-exposed sub-events, not direct USB packets or hardware latency.
Mouse DPI Distance and Repeated-Run Method
The DPI analyzer asks for physical travel in centimeters or inches and requests Pointer Lock with unadjustedMovement: true. A resolved modern promise is reported as an accepted request; a legacy void result is reported as unconfirmed, and rejection is reported as a standard movement fallback. The page cannot independently inspect whether every movement unit equals a native sensor count. Operating-system acceleration, browser policy, scaling, remote input, and device handling may remain.
Signed horizontal movementX values are accumulated during an active run. Distance converts with inches = centimeters / 2.54, and estimated DPI is abs(accumulatedMovementUnits) / distanceInches. Three runs are displayed. Their median is the sorted middle value, mean is the arithmetic average, and variation is (maximum − minimum) / median × 100. A close group supports repeatability, not exact hardware calibration; zero distance, non-finite input, and a run with zero movement are rejected.
Mouse Diagnostics: Buttons, Repeats, and Accuracy
The mouse test listens for pointerdown, pointerup, and pointermove inside its dedicated test area, ignores touch contacts as mouse-button data, and follows standardized browser button values: 0 primary, 1 auxiliary, 2 secondary, 3 Back, and 4 Forward. Other integer values use an explicit unknown fallback. A stage-level contextmenu handler prevents the right-click menu only within that test area, while a stage-level auxclick handler reduces unintended auxiliary actions. No global context-menu restriction is installed. wheel is registered non-passively because the isolated stage intentionally prevents page scrolling while it classifies negative deltaY as up, positive deltaY as down, and nonzero deltaX as horizontal. These are browser wheel events, not physical notch or encoder counts. Local pointer coordinates and an aggregate movement-event count are displayed without storing a trajectory. Button press counts and wheel direction totals are retained locally; the visible chronological log is bounded to forty records.
The mouse double click test uses pointerdown rather than the higher-level dblclick event. Only non-touch input matching the selected button is accepted. Each handler reads the monotonic high-resolution performance.now() clock, and the current timestamp is subtracted from the previous accepted timestamp for that same browser button. Different buttons are stored in separate timing slots. Non-finite or negative timestamps and non-positive intervals are rejected. History is capped at fifty events. Diagnostic mode labels a positive interval less than or equal to the visible default 80 ms threshold as a possible short repeat; the user can select 40–250 ms. This boundary is a heuristic, not an industry failure standard. Manual mode reports intentional double-click intervals without applying the chatter label, touch is excluded, and configuration changes reset prior samples to avoid mixing test conditions.
The mouse accuracy test places one target at a time inside the play area. Horizontal centers use radius + 10 CSS pixels through stage width − radius − 10 CSS pixels; vertical placement applies the same padding below a reserved 58-pixel session-control band. The full circle therefore remains inside the bounds and never appears beneath Start, Resume, or Restart. Small, Medium, and Large are radii of 15, 22, and 30 CSS pixels. The first pointerdown in the stage ends an attempt: distance less than or equal to radius is a hit, while an outside click is a miss; events originating from the in-stage control bar are excluded. Timing starts with performance.now() immediately after the target becomes visible and ends at that first stage pointer-down, excluding setup time.
Center offset uses Euclidean distance sqrt((cx − tx)² + (cy − ty)²). Normalized offset is distancePx / targetRadius, where zero is the exact center and one is the hit boundary. Center-offset averages use hits only, while selection-time average, median, best, and population standard deviation use every completed attempt because a miss also ends its target. Hit rate is hits divided by completed attempts. Sessions retain at most the configured 20, 30, or 50 samples. If a ResizeObserver detects a size change during an active target, that target is discarded without an attempt, the session pauses, and Resume safely places a replacement with a restarted timer. Touch input is allowed only as separately labeled practice and is not presented as comparable mouse data.
Precision, Reproducibility, and Boundaries
Calculations retain JavaScript numeric precision and round only for display—usually one decimal for FPS and two for frame time. Canvas charts cap device pixel ratio at two and update in batches, reducing the chance that the visualizer itself adds heavy per-frame work. Continuous tools retain bounded arrays. Event listeners, observers, and animation loops naturally end on page navigation in this static multi-page application.
For reproducible tests, use the same current browser, display, window position, duration, power mode, and background workload. Keep the tab visible, run at least three samples, and change one variable at a time. Results are observational and informational: they cannot certify a monitor, GPU, mouse, neurological response, or external game. Source calculations are unit-tested so the documentation and production logic remain aligned.