emilk/egui · error
should have a Performance
Error message
should have a Performance
What it means
now_sec calls .performance() on the browser Window and panics with 'should have a Performance' if it returns None. Performance access is required to obtain a monotonic high-resolution clock; some environments provide a window without the Performance API.
Source
Thrown at crates/eframe/src/web/mod.rs:107
/// Focus the given element without scrolling it into view.
///
/// Scrolling the element into view would scroll the whole page when
/// the app is embedded in a larger scrollable page,
/// see <https://github.com/emilk/egui/issues/8295>.
pub(crate) fn focus_without_scroll(element: &web_sys::HtmlElement) -> Result<(), JsValue> {
let options = web_sys::FocusOptions::new();
options.set_prevent_scroll(true);
element.focus_with_options(&options)
}
/// Current time in seconds (since undefined point in time).
///
/// Monotonically increasing.
pub fn now_sec() -> f64 {
web_sys::window()
.expect("should have a Window")
.performance()
.expect("should have a Performance")
.now()
/ 1000.0
}
/// The native GUI scale factor, taking into account the browser zoom.
///
/// Corresponds to [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) in JavaScript.
pub fn native_pixels_per_point() -> f32 {
let pixels_per_point = web_sys::window().unwrap().device_pixel_ratio() as f32;
if pixels_per_point > 0.0 && pixels_per_point.is_finite() {
pixels_per_point
} else {
1.0
}
}
/// Ask the browser about the preferred system theme.
///View on GitHub (pinned to 441971a776)
Solutions
- Use a browser or webview that supports the Performance API (any modern browser does).
- Wrap timing with a fallback: check performance() and fall back to Date::now() before calling now_sec.
- In tests, polyfill/mock window.performance.now before invoking the code.
Example fix
// before let t = eframe::web::now_sec(); // after let t = web_sys::window().and_then(|w| w.performance()).map(|p| p.now() / 1000.0).unwrap_or((js_sys::Date::now() / 1000.0) as f64);
Defensive patterns
Strategy: fallback
Validate before calling
let perf_ok = web_sys::window().map(|w| w.performance().is_some()).unwrap_or(false);
Type guard
fn performance_available() -> bool { web_sys::window().and_then(|w| w.performance()).is_some() } Try / catch
// Guard before call; on absence use js_sys::Date::now()/1000.0 as a fallback clock.
Prevention
- Target browsers/webviews that support the Performance API.
- Polyfill or mock window.performance in test environments.
- Prefer your own time source in code that must run in minimal webviews.
When it happens
Trigger: Calling now_sec (or auto_save_if_needed/save which use it) in a browser context where window.performance is unavailable — older browsers, some embedded webviews, or mocked Window objects in tests.
Common situations: Running egui/eframe apps inside minimal WebView controls that don't expose the Performance API; using a test double for web_sys::window that lacks performance; very old browser targets.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- should have a Window
- Your app must implement `as_any_mut`, but it doesn't
- Failed to query about WebGL2 context
- ERROR: {msg}
- Failed to save screenshot to {path:?}: {err}
AI-assisted analysis of emilk/egui@441971a776 (2026-09-12).
Data as JSON: /api/errors/7718a4c703bc7e83.
Report an issue: GitHub.