FPS meter and render profiling
Senzoukria ships two frame-rate readouts, a global meter toggled with Ctrl+Shift+F and a per-chart counter next to the price axis, plus a render pass profiler whose timings go to the console in development or when opted in.
Senzoukria · Documentation · Updated September 2026
Where to find it
- Global meter
- Ctrl+Shift+F toggles it; the choice is remembered between launches
- Chart counter
- Top of the chart, left of the price axis, refreshed every 500 ms
- Rendering sharpness
- Settings → Performance → 1×, 1.5× or 2×; default 1.5×
- Pass profiler output
- Console lines tagged [fp-perf], once per second, dev builds or opt-in
What it does
The global FPS meter is a diagnostic strip meant to be switched on for thirty seconds to check a number. It shows frames per second over the last second, the worst frame time in that second in milliseconds, the detected screen refresh rate (median of 60 frame intervals measured at mount), and, after the window regains focus, the average and minimum FPS measured while it was in the background. That last figure answers whether the app is being throttled behind another application. When Windows requests reduced motion, the strip says animations OFF (Windows), because the background is then deliberately frozen.
The chart counter is a different measurement: since September 2026 it counts the frames the main thread actually delivers to the screen while the chart is visible, not the number of repaints. It therefore follows the panel rate (60, 100, 144, 240) and drops only on a real stutter. The repaint count stayed in the [fp-perf] logs, under painted=. A pause longer than one second without a frame, for instance a hidden chart or a minimised window, restarts the measurement instead of counting as a stall, and the chart itself still paints only when something changes, through a frame loop that keeps at most one pending frame and none while the chart is hidden.
Readouts and thresholds
| Readout | Green | Yellow | Red |
|---|---|---|---|
| Global meter (vs detected refresh rate) | ≥ 92 % of the refresh rate | ≥ 70 % | below 70 % |
| Chart counter (vs best of the last 10 readings) | ≥ 90 % of the recent peak and ≥ 50 fps | ≥ 70 % of the peak, or 30 to 49 fps | below 70 % of the peak, or under 30 fps |
| Background stats | minimum ≥ 60 fps | minimum below 60 fps | — |
Settings
| Setting | Default | What it changes |
|---|---|---|
| Rendering sharpness | 1.5× | Cap on the canvas pixel ratio. 1× halves the pixels on HiDPI screens; 2× is sharpest and heaviest. Options: 1×, 1.5×, 2×. |
| Performance mode | Balanced | Performance sets 1×, Balanced 1.5×, Precision 2× (together with other knobs). Touching a knob by hand switches the mode to Manual. |
| Perf logs | Off in release builds | Set localStorage senzoukria.perfLogs to 1 and reload to enable the [fp-perf] console lines on a release build. |
Render pass profiling
Every drawing pass of the footprint renderer (cells, profiles, GEX levels, news markers, the DOM panel commit, React commits) is timed through a shared profiler. Once per second the canvas flushes it and prints a ranked line to the console: total and average milliseconds per pass, the worst pass, the number of React commits and the DOM panel cost. The profiler holds no reference to the canvas or React, and popout windows have their own instance, so measurements never mix across windows.
These logs are silent in distributed builds because the WebView console retains what it is written, and a log per second over hours is a memory cost. They are on in npm run dev and can be enabled on a user's machine with the opt-in key above.
Limits or pitfalls
Reading the numbers:
- The chart counter stops rather than reports zero: when the chart is hidden or the window inactive, the measurement is paused and restarts from scratch on the next frame.
- Colours are relative to the recent peak, so the same 120 fps reads green on a 120 Hz screen and amber on a 240 Hz one.
- The detected refresh rate is a median of frame intervals; on a machine that cannot keep up it can read below the true panel rate.
- The global meter runs its own requestAnimationFrame loop; leave it off outside diagnostics.
- Background measurements need the window to lose focus and come back; the strip shows the last background period only.
Related pages
This page in other languages
Frequently asked questions
- How do I show the FPS meter?
- Press Ctrl+Shift+F. Press it again or click ✕ to hide it. The state is stored under senz.fpsMeter and restored at the next launch.
- The chart counter reads 45 fps on a 144 Hz monitor. What does that mean?
- It means the main thread delivered 45 frames in the last second while the chart was visible, so something is holding it up. The colour is relative: green needs at least 90 % of the best of the last ten readings and 50 fps, and anything under 30 fps is red whatever the screen. Compare with the global meter, which measures the animation loop against the detected refresh rate.
- Where are the render profiling numbers?
- In the developer console as [fp-perf] lines once per second, available in development builds or after setting localStorage senzoukria.perfLogs to 1 and reloading.