{"record":{"id":"7718a4c703bc7e83","repo":"emilk/egui","slug":"should-have-a-performance","errorCode":null,"errorMessage":"should have a Performance","messagePattern":"should have a Performance","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/eframe/src/web/mod.rs","lineNumber":107,"sourceCode":"/// Focus the given element without scrolling it into view.\n///\n/// Scrolling the element into view would scroll the whole page when\n/// the app is embedded in a larger scrollable page,\n/// see <https://github.com/emilk/egui/issues/8295>.\npub(crate) fn focus_without_scroll(element: &web_sys::HtmlElement) -> Result<(), JsValue> {\n    let options = web_sys::FocusOptions::new();\n    options.set_prevent_scroll(true);\n    element.focus_with_options(&options)\n}\n\n/// Current time in seconds (since undefined point in time).\n///\n/// Monotonically increasing.\npub fn now_sec() -> f64 {\n    web_sys::window()\n        .expect(\"should have a Window\")\n        .performance()\n        .expect(\"should have a Performance\")\n        .now()\n        / 1000.0\n}\n\n/// The native GUI scale factor, taking into account the browser zoom.\n///\n/// Corresponds to [`window.devicePixelRatio`](https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio) in JavaScript.\npub fn native_pixels_per_point() -> f32 {\n    let pixels_per_point = web_sys::window().unwrap().device_pixel_ratio() as f32;\n    if pixels_per_point > 0.0 && pixels_per_point.is_finite() {\n        pixels_per_point\n    } else {\n        1.0\n    }\n}\n\n/// Ask the browser about the preferred system theme.\n///","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/emilk/egui/blob/441971a776322a482e371775219380eca812cfa9/crates/eframe/src/web/mod.rs#L89-L125","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet t = eframe::web::now_sec();\n// after\nlet 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);","handlingStrategy":"fallback","validationCode":"let perf_ok = web_sys::window().map(|w| w.performance().is_some()).unwrap_or(false);","typeGuard":"fn performance_available() -> bool { web_sys::window().and_then(|w| w.performance()).is_some() }","tryCatchPattern":"// Guard before call; on absence use js_sys::Date::now()/1000.0 as a fallback clock.","preventionTips":["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."],"tags":["wasm","web","browser-environment","panic"],"backgroundTag":"unsupported-platform","analyzedSha":"441971a776322a482e371775219380eca812cfa9","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}