From bc063c58b74740a98b4fba3fb747e156af7ed385 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 19 Jun 2023 12:04:06 -0500 Subject: [PATCH] throttle history updates to 100ms --- packages/router/src/components/router.rs | 70 ++++++++++++++++++++++++ packages/router/src/history/web.rs | 28 ++++++++-- packages/router/src/router_cfg.rs | 22 ++++++++ 3 files changed, 116 insertions(+), 4 deletions(-) diff --git a/packages/router/src/components/router.rs b/packages/router/src/components/router.rs index e62f48c64..7c6f5f0a4 100644 --- a/packages/router/src/components/router.rs +++ b/packages/router/src/components/router.rs @@ -14,6 +14,18 @@ pub struct RouterConfigFactory { config: RefCell RouterConfig>>>, } +#[cfg(feature = "serde")] +impl Default for RouterConfigFactory +where + ::Err: std::fmt::Display, + R: serde::Serialize + serde::de::DeserializeOwned, +{ + fn default() -> Self { + Self::from(RouterConfig::default) + } +} + +#[cfg(not(feature = "serde"))] impl Default for RouterConfigFactory where ::Err: std::fmt::Display, @@ -31,6 +43,19 @@ impl RouterConfig + 'static> From for RouterCo } } +#[cfg(feature = "serde")] +/// The props for [`GenericRouter`]. +#[derive(Props)] +pub struct GenericRouterProps +where + ::Err: std::fmt::Display, + R: serde::Serialize + serde::de::DeserializeOwned, +{ + #[props(default, into)] + config: RouterConfigFactory, +} + +#[cfg(not(feature = "serde"))] /// The props for [`GenericRouter`]. #[derive(Props)] pub struct GenericRouterProps @@ -41,6 +66,7 @@ where config: RouterConfigFactory, } +#[cfg(not(feature = "serde"))] impl PartialEq for GenericRouterProps where ::Err: std::fmt::Display, @@ -51,6 +77,19 @@ where } } +#[cfg(feature = "serde")] +impl PartialEq for GenericRouterProps +where + ::Err: std::fmt::Display, + R: serde::Serialize + serde::de::DeserializeOwned, +{ + fn eq(&self, _: &Self) -> bool { + // prevent the router from re-rendering when the initial url or config changes + true + } +} + +#[cfg(not(feature = "serde"))] /// A component that renders the current route. pub fn GenericRouter(cx: Scope>) -> Element where @@ -79,3 +118,34 @@ where GenericOutlet:: {} } } + +#[cfg(feature = "serde")] +/// A component that renders the current route. +pub fn GenericRouter(cx: Scope>) -> Element +where + ::Err: std::fmt::Display, + R: serde::Serialize + serde::de::DeserializeOwned, +{ + use_context_provider(cx, || { + #[allow(unreachable_code, unused_variables)] + if let Some(outer) = cx.consume_context::>() { + let msg = "Router components should not be nested within each other"; + error!("{msg}, inner will be inactive and transparent"); + #[cfg(debug_assertions)] + panic!("{}", msg); + } + let router = GenericRouterContext::new( + (cx.props + .config + .config + .take() + .expect("use_context_provider ran twice"))(), + cx.schedule_update_any(), + ); + router + }); + + render! { + GenericOutlet:: {} + } +} diff --git a/packages/router/src/history/web.rs b/packages/router/src/history/web.rs index da8f4952f..2e5c957a6 100644 --- a/packages/router/src/history/web.rs +++ b/packages/router/src/history/web.rs @@ -104,8 +104,18 @@ impl WebHistory { let myself = Self::new_inner( prefix, do_scroll_restoration, - EventListener::new(&document, "scroll", move |_| { - update_scroll::(&w, &h); + EventListener::new(&document, "scroll", { + let mut last_updated = 0.0; + move |evt| { + // the time stamp in milliseconds + let time_stamp = evt.time_stamp(); + // throttle the scroll event to 100ms + if (time_stamp - last_updated) < 100.0 { + return; + } + update_scroll::(&w, &h); + last_updated = time_stamp; + } }), ); @@ -134,8 +144,18 @@ impl WebHistory { let myself = Self::new_inner( prefix, do_scroll_restoration, - EventListener::new(&document, "scroll", move |_| { - update_scroll::(&w, &h); + EventListener::new(&document, "scroll", { + let mut last_updated = 0.0; + move |evt| { + // the time stamp in milliseconds + let time_stamp = evt.time_stamp(); + // throttle the scroll event to 100ms + if (time_stamp - last_updated) < 100.0 { + return; + } + update_scroll::(&w, &h); + last_updated = time_stamp; + } }), ); diff --git a/packages/router/src/router_cfg.rs b/packages/router/src/router_cfg.rs index fae60e28f..637f1d324 100644 --- a/packages/router/src/router_cfg.rs +++ b/packages/router/src/router_cfg.rs @@ -30,6 +30,28 @@ pub struct RouterConfig { pub(crate) on_update: Option>, } +#[cfg(feature = "serde")] +impl Default for RouterConfig +where + ::Err: std::fmt::Display, + R: serde::Serialize + serde::de::DeserializeOwned, +{ + fn default() -> Self { + Self { + failure_external_navigation: FailureExternalNavigation::, + history: { + #[cfg(all(target_arch = "wasm32", feature = "web"))] + let history = Box::>::default(); + #[cfg(not(all(target_arch = "wasm32", feature = "web")))] + let history = Box::>::default(); + history + }, + on_update: None, + } + } +} + +#[cfg(not(feature = "serde"))] impl Default for RouterConfig where ::Err: std::fmt::Display,