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

  1. Use a browser or webview that supports the Performance API (any modern browser does).
  2. Wrap timing with a fallback: check performance() and fall back to Date::now() before calling now_sec.
  3. 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

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


AI-assisted analysis of emilk/egui@441971a776 (2026-09-12). Data as JSON: /api/errors/7718a4c703bc7e83. Report an issue: GitHub.