feat(browser): add opt-in FPS counter overlay
feat(browser): add opt-in FPS counter overlay
#402 in DioxusLabs/blitz — merged 2026-04-27
Summary
- Adds an opt-in FPS counter overlay to the Blitz browser UI (
apps/browser), gated behind a--show-fpsCLI flag. - Frame timing is measured via a
dioxus_native::CustomPaintSourcewhoserendermethod fires once per real paint — i.e. the wall-clock delta between successiveRedrawRequestedevents, so the displayed FPS reflects actual paint cadence. - All changes are localized to
apps/browser/; no engine packages were modified.
Addresses the "FPS counter" checklist item in #363.
Design
apps/browser/src/fps_overlay.rs(new) —FpsStats(60-frame ring of frame durations),FpsPaintSource(implCustomPaintSource, recordsInstant::now()deltas inrender(), resets onsuspend()), andFpsOverlay(Dioxus component that registers the source viause_wgpu, polls the stats every 250ms, and renders a 1×1 tick canvas plus the visible HUD).apps/browser/src/main.rs— parses--show-fpsfromstd::env::args()and threads aShowFpsnewtype throughdioxus_native::launch_cfg's context vector. The overlay component is conditionally mounted in the chrome.apps/browser/assets/browser.css—.fps-overlay(fixed top-right, semi-transparent black, green monospace) and.fps-tick(1×1 invisible canvas that drives the per-frame tick). Note: the tick canvas usesopacity: 0.01rather than0becauseblitz-paint's renderer short-circuits elements withopacity: 0, which would otherwise preventCustomPaintSource::renderfrom firing.apps/browser/Cargo.toml— addstokio = { workspace = true, features = ["time"] }for the 250ms polling task (already in the workspace lockfile).
Test plan
-
cargo build -p browser— clean build. -
cargo run -p browser— overlay does NOT appear (no flag). -
cargo run -p browser -- --show-fps— overlay appears top-right, below the urlbar. - Load an animated page (e.g. anything with CSS animation) — FPS rises to a steady value.
- Load a static page — FPS settles to ~0 within ~1s.
- Existing Alt+D / Alt+H devtools toggles still work.
🤖 Generated with Claude Code
Last updated 2026-05-14
Links to this note
Credits
Merged pull requests, newest first.