From dffe195cdc46b89025faafebd2f0bf76205c31ca Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 13:16:20 -0500 Subject: [PATCH 01/10] Fix two warnings --- leptos_dom/src/components/dyn_child.rs | 9 ++++----- leptos_dom/src/hydration.rs | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/leptos_dom/src/components/dyn_child.rs b/leptos_dom/src/components/dyn_child.rs index 107dbafb3..f0bfd388c 100644 --- a/leptos_dom/src/components/dyn_child.rs +++ b/leptos_dom/src/components/dyn_child.rs @@ -154,10 +154,7 @@ where let component = DynChildRepr::new(); #[cfg(all(target_arch = "wasm32", feature = "web"))] - let (frag, closing) = ( - component.document_fragment.clone(), - component.closing.node.clone(), - ); + let closing = component.closing.node.clone(); let child = component.child.clone(); @@ -189,7 +186,9 @@ where // or to reuse it in the case of a text node // TODO check does this still detect moves correctly? - let was_child_moved = prev_t.is_none() && child.get_closing_node().next_sibling().as_ref() != Some(&closing); + let was_child_moved = prev_t.is_none() + && child.get_closing_node().next_sibling().as_ref() + != Some(&closing); // If the previous child was a text node, we would like to // make use of it again if our current child is also a text diff --git a/leptos_dom/src/hydration.rs b/leptos_dom/src/hydration.rs index d42216797..5100b707e 100644 --- a/leptos_dom/src/hydration.rs +++ b/leptos_dom/src/hydration.rs @@ -3,9 +3,9 @@ use std::{cell::RefCell, fmt::Display}; #[cfg(all(target_arch = "wasm32", feature = "web"))] use once_cell::unsync::Lazy as LazyCell; -/// We can tell if we start in hydration mode by checking to see if the -/// id "_0" is present in the DOM. If it is, we know we are hydrating from -/// the server, if not, we are starting off in CSR +// We can tell if we start in hydration mode by checking to see if the +// id "_0-0-0" is present in the DOM. If it is, we know we are hydrating from +// the server, if not, we are starting off in CSR #[cfg(all(target_arch = "wasm32", feature = "web"))] thread_local! { static IS_HYDRATING: RefCell> = RefCell::new(LazyCell::new(|| { From e01c565de1b5ec0bc332d3aca2587b48afc9bc5d Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 13:16:30 -0500 Subject: [PATCH 02/10] Improve tracing formatting --- leptos_reactive/src/effect.rs | 12 +-- leptos_reactive/src/memo.rs | 18 ++-- leptos_reactive/src/resource.rs | 4 +- leptos_reactive/src/signal.rs | 100 +++++++++---------- leptos_reactive/src/signal_wrappers_read.rs | 36 ++++++- leptos_reactive/src/signal_wrappers_write.rs | 4 +- 6 files changed, 102 insertions(+), 72 deletions(-) diff --git a/leptos_reactive/src/effect.rs b/leptos_reactive/src/effect.rs index 8cbe46b29..9e90b6522 100644 --- a/leptos_reactive/src/effect.rs +++ b/leptos_reactive/src/effect.rs @@ -53,7 +53,7 @@ use std::fmt::Debug; level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::() ) ) @@ -107,7 +107,7 @@ where level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::() ) ) @@ -128,7 +128,7 @@ where level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::() ) ) @@ -172,8 +172,8 @@ where level = "debug", skip_all, fields( - id = %format!("{:?}", id), - defined_at = %format!("{:?}", self.defined_at), + id = ?id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -220,7 +220,7 @@ impl EffectId { level = "debug", skip_all, fields( - id = %format!("{:?}", self), + id = ?self, ) ) )] diff --git a/leptos_reactive/src/memo.rs b/leptos_reactive/src/memo.rs index e2e528b06..fc48ff532 100644 --- a/leptos_reactive/src/memo.rs +++ b/leptos_reactive/src/memo.rs @@ -60,7 +60,7 @@ use std::fmt::Debug; level = "trace", skip_all, fields( - cx = %format!("{:?}", cx.id), + cx = ?cx.id, ) ) )] @@ -155,8 +155,8 @@ impl UntrackedGettableSignal for Memo { name = "Memo::get_untracked()", skip_all, fields( - id = %format!("{:?}", self.0.id), - defined_at = %format!("{:?}", self.1), + id = ?self.0.id, + defined_at = %self.1, ty = %std::any::type_name::() ) ) @@ -177,8 +177,8 @@ impl UntrackedGettableSignal for Memo { name = "Memo::with_untracked()", skip_all, fields( - id = %format!("{:?}", self.0.id), - defined_at = %format!("{:?}", self.1), + id = ?self.0.id, + defined_at = %self.1, ty = %std::any::type_name::() ) ) @@ -217,8 +217,8 @@ where level = "trace", skip_all, fields( - id = %format!("{:?}", self.0.id), - defined_at = %format!("{:?}", self.1) + id = ?self.0.id, + defined_at = %self.1 ) ) )] @@ -256,8 +256,8 @@ where level = "trace", skip_all, fields( - id = %format!("{:?}", self.0.id), - defined_at = %format!("{:?}", self.1), + id = ?self.0.id, + defined_at = %self.1, ty = %std::any::type_name::() ) ) diff --git a/leptos_reactive/src/resource.rs b/leptos_reactive/src/resource.rs index 2d2491c4e..0aee7e6f9 100644 --- a/leptos_reactive/src/resource.rs +++ b/leptos_reactive/src/resource.rs @@ -89,7 +89,7 @@ where level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::(), signal_ty = %std::any::type_name::(), ) @@ -208,7 +208,7 @@ where level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::(), signal_ty = %std::any::type_name::(), ) diff --git a/leptos_reactive/src/signal.rs b/leptos_reactive/src/signal.rs index ab85a4a1b..d953858fd 100644 --- a/leptos_reactive/src/signal.rs +++ b/leptos_reactive/src/signal.rs @@ -51,7 +51,7 @@ use thiserror::Error; level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ty = %std::any::type_name::() ) ) @@ -72,7 +72,7 @@ pub fn create_signal(cx: Scope, value: T) -> (ReadSignal, WriteSignal) level = "trace", skip_all, fields( - scope = %format!("{:?}", cx.id), + scope = ?cx.id, ) ) )] @@ -154,8 +154,8 @@ impl UntrackedGettableSignal for ReadSignal { name = "ReadSignal::get_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -174,8 +174,8 @@ impl UntrackedGettableSignal for ReadSignal { name = "ReadSignal::with_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -214,8 +214,8 @@ where name = "ReadSignal::with()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -254,8 +254,8 @@ where name = "ReadSignal::get()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -391,8 +391,8 @@ where name = "WriteSignal::set_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -409,8 +409,8 @@ where name = "WriteSignal::updated_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -426,8 +426,8 @@ where name = "WriteSignal::update_returning_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -468,8 +468,8 @@ where level = "trace", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -506,8 +506,8 @@ where name = "WriteSignal::update_returning()" skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -542,8 +542,8 @@ where name = "WriteSignal::set()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -691,8 +691,8 @@ impl UntrackedGettableSignal for RwSignal { name = "RwSignal::get_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -712,8 +712,8 @@ impl UntrackedGettableSignal for RwSignal { name = "RwSignal::with_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -731,8 +731,8 @@ impl UntrackedSettableSignal for RwSignal { name = "RwSignal::set_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -749,8 +749,8 @@ impl UntrackedSettableSignal for RwSignal { name = "RwSignal::update_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -766,8 +766,8 @@ impl UntrackedSettableSignal for RwSignal { name = "RwSignal::update_returning_untracked()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -807,8 +807,8 @@ where name = "RwSignal::with()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -838,8 +838,8 @@ where name = "RwSignal::get()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -875,8 +875,8 @@ where name = "RwSignal::update()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -911,8 +911,8 @@ where name = "RwSignal::update_returning()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -942,8 +942,8 @@ where name = "RwSignal::set()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -975,8 +975,8 @@ where name = "RwSignal::read_only()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -1013,8 +1013,8 @@ where name = "RwSignal::write_only()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -1050,8 +1050,8 @@ where name = "RwSignal::split()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -1084,8 +1084,8 @@ where name = "RwSignal::to_stream()", skip_all, fields( - id = %format!("{:?}", self.id), - defined_at = %format!("{:?}", self.defined_at), + id = ?self.id, + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) diff --git a/leptos_reactive/src/signal_wrappers_read.rs b/leptos_reactive/src/signal_wrappers_read.rs index d90d7b9cf..415213fa5 100644 --- a/leptos_reactive/src/signal_wrappers_read.rs +++ b/leptos_reactive/src/signal_wrappers_read.rs @@ -109,7 +109,7 @@ where level = "trace", skip_all, fields( - cx = %format!("{:?}", cx.id) + cx = ?cx.id ) ) )] @@ -163,7 +163,7 @@ where level = "trace", skip_all, fields( - defined_at = %format!("{:?}", self.defined_at), + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -204,7 +204,7 @@ where level = "trace", skip_all, fields( - defined_at = %format!("{:?}", self.defined_at), + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) @@ -425,6 +425,18 @@ where /// assert_eq!(above_3(&double_count), true); /// # }); /// ``` + #[cfg_attr( + debug_assertions, + instrument( + level = "trace", + name = "MaybeSignal::derive()", + skip_all, + fields( + cx = ?cx.id, + ty = %std::any::type_name::() + ) + ) + )] pub fn derive(cx: Scope, derived_signal: impl Fn() -> T + 'static) -> Self { Self::Dynamic(Signal::derive(cx, derived_signal)) } @@ -461,6 +473,15 @@ where /// assert_eq!(static_value(), "Bob"); /// }); /// ``` + #[cfg_attr( + debug_assertions, + instrument( + level = "trace", + name = "MaybeSignal::derive()", + skip_all, + fields(ty = %std::any::type_name::()) + ) + )] pub fn with(&self, f: impl FnOnce(&T) -> U) -> U { match &self { Self::Static(value) => f(value), @@ -492,6 +513,15 @@ where /// assert_eq!(above_3(&static_value.into()), true); /// # }); /// ``` + #[cfg_attr( + debug_assertions, + instrument( + level = "trace", + name = "MaybeSignal::derive()", + skip_all, + fields(ty = %std::any::type_name::()) + ) + )] pub fn get(&self) -> T where T: Clone, diff --git a/leptos_reactive/src/signal_wrappers_write.rs b/leptos_reactive/src/signal_wrappers_write.rs index dd025e847..ea9946108 100644 --- a/leptos_reactive/src/signal_wrappers_write.rs +++ b/leptos_reactive/src/signal_wrappers_write.rs @@ -92,7 +92,7 @@ where level = "trace", skip_all, fields( - cx = %format!("{:?}", cx.id), + cx = ?cx.id, ) ) )] @@ -130,7 +130,7 @@ where level = "trace", skip_all, fields( - defined_at = %format!("{:?}", self.defined_at), + defined_at = %self.defined_at, ty = %std::any::type_name::() ) ) From ed940f577a267e74ca04e95fe80db1a95e69f861 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 13:32:40 -0500 Subject: [PATCH 03/10] Add tracing for event handlers --- leptos_dom/examples/test-bench/src/main.rs | 4 ++ leptos_dom/src/events.rs | 39 ++++++++++++- leptos_dom/src/helpers.rs | 64 ++++++++++++++++++++++ leptos_dom/src/html.rs | 26 ++++++++- leptos_dom/src/lib.rs | 13 ++++- 5 files changed, 141 insertions(+), 5 deletions(-) diff --git a/leptos_dom/examples/test-bench/src/main.rs b/leptos_dom/examples/test-bench/src/main.rs index 53410feb6..b04c0f8df 100644 --- a/leptos_dom/examples/test-bench/src/main.rs +++ b/leptos_dom/examples/test-bench/src/main.rs @@ -43,6 +43,7 @@ fn view_fn(cx: Scope) -> impl IntoView { let (is_a, set_is_a) = create_signal(cx, true); let handle_toggle = move |_| { + trace!("toggling"); if is_a() { set_b(a()); @@ -91,5 +92,8 @@ fn Example(cx: Scope) -> impl IntoView { view! { cx,

"Example"

+ } } diff --git a/leptos_dom/src/events.rs b/leptos_dom/src/events.rs index ec7345e46..11300a57e 100644 --- a/leptos_dom/src/events.rs +++ b/leptos_dom/src/events.rs @@ -16,10 +16,20 @@ thread_local! { pub fn add_event_listener( target: &web_sys::Element, event_name: Cow<'static, str>, - cb: impl FnMut(E) + 'static, + mut cb: impl FnMut(E) + 'static, ) where E: FromWasmAbi + 'static, { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move |e| { + let _guard = span.enter(); + cb(e); + }; + } + } + let cb = Closure::wrap(Box::new(cb) as Box).into_js_value(); let key = event_delegation_key(&event_name); _ = js_sys::Reflect::set(target, &JsValue::from_str(&key), &cb); @@ -31,10 +41,20 @@ pub fn add_event_listener( pub fn add_event_listener_undelegated( target: &web_sys::Element, event_name: &str, - cb: impl FnMut(E) + 'static, + mut cb: impl FnMut(E) + 'static, ) where E: FromWasmAbi + 'static, { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move |e| { + let _guard = span.enter(); + cb(e); + }; + } + } + let event_name = intern(event_name); let cb = Closure::wrap(Box::new(cb) as Box).into_js_value(); _ = target.add_event_listener_with_callback(event_name, cb.unchecked_ref()); @@ -97,7 +117,20 @@ pub(crate) fn add_delegated_event_listener(event_name: Cow<'static, str>) { } }; - crate::window_event_listener(&event_name, handler); + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let handler = move |e| { + let _guard = span.enter(); + handler(e); + }; + } + } + + let handler = Box::new(handler) as Box; + let handler = Closure::wrap(handler).into_js_value(); + _ = crate::window() + .add_event_listener_with_callback(&event_name, handler.unchecked_ref()); // register that we've created handler events.insert(event_name); diff --git a/leptos_dom/src/helpers.rs b/leptos_dom/src/helpers.rs index ef25104f7..6c7da605e 100644 --- a/leptos_dom/src/helpers.rs +++ b/leptos_dom/src/helpers.rs @@ -71,21 +71,57 @@ pub fn event_target_checked(ev: &web_sys::Event) -> bool { /// Runs the given function between the next repaint /// using [`Window.requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). +#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))] pub fn request_animation_frame(cb: impl FnOnce() + 'static) { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move || { + let _guard = span.enter(); + cb(); + }; + } + } + let cb = Closure::once_into_js(cb); _ = window().request_animation_frame(cb.as_ref().unchecked_ref()); } /// Queues the given function during an idle period /// using [`Window.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestIdleCallback). +#[cfg_attr(debug_assertions, instrument(level = "trace", skip_all))] pub fn request_idle_callback(cb: impl Fn() + 'static) { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move || { + let _guard = span.enter(); + cb(); + }; + } + } + let cb = Closure::wrap(Box::new(cb) as Box).into_js_value(); _ = window().request_idle_callback(cb.as_ref().unchecked_ref()); } /// Executes the given function after the given duration of time has passed. /// [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout). +#[cfg_attr( + debug_assertions, + instrument(level = "trace", skip_all, fields(duration = ?duration)) +)] pub fn set_timeout(cb: impl FnOnce() + 'static, duration: Duration) { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move || { + let _guard = span.enter(); + cb(); + }; + } + } + let cb = Closure::once_into_js(Box::new(cb) as Box); _ = window().set_timeout_with_callback_and_timeout_and_arguments_0( cb.as_ref().unchecked_ref(), @@ -107,10 +143,24 @@ impl IntervalHandle { /// Repeatedly calls the given function, with a delay of the given duration between calls. /// See [`setInterval()`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval). +#[cfg_attr( + debug_assertions, + instrument(level = "trace", skip_all, fields(duration = ?duration)) +)] pub fn set_interval( cb: impl Fn() + 'static, duration: Duration, ) -> Result { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move || { + let _guard = span.enter(); + cb(); + }; + } + } + let cb = Closure::wrap(Box::new(cb) as Box).into_js_value(); let handle = window() .set_interval_with_callback_and_timeout_and_arguments_0( @@ -121,10 +171,24 @@ pub fn set_interval( } /// Adds an event listener to the `Window`. +#[cfg_attr( + debug_assertions, + instrument(level = "trace", skip_all, fields(event_name = %event_name)) +)] pub fn window_event_listener( event_name: &str, cb: impl Fn(web_sys::Event) + 'static, ) { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let cb = move |e| { + let _guard = span.enter(); + cb(e); + }; + } + } + if !is_server() { let handler = Box::new(cb) as Box; diff --git a/leptos_dom/src/html.rs b/leptos_dom/src/html.rs index 184ba2a32..2349c9202 100644 --- a/leptos_dom/src/html.rs +++ b/leptos_dom/src/html.rs @@ -568,15 +568,39 @@ impl HtmlElement { /// Adds an event listener to this element. #[track_caller] + #[cfg_attr( + debug_assertions, + instrument( + level = "trace", + name = "event handler", + skip_all, + fields( + tag = %self.element.name(), + event = %event.name(), + defined_at = %std::panic::Location::caller() + ) + ) + )] pub fn on( self, event: E, - event_handler: impl FnMut(E::EventType) + 'static, + #[allow(unused_mut)] // used for tracing in debug + mut event_handler: impl FnMut(E::EventType) + 'static, ) -> Self { #[cfg(all(target_arch = "wasm32", feature = "web"))] { let event_name = event.name(); + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + let span = ::tracing::Span::current(); + let event_handler = move |e| { + let _guard = span.enter(); + event_handler(e); + }; + } + } + if event.bubbles() { add_event_listener(self.element.as_ref(), event_name, event_handler); } else { diff --git a/leptos_dom/src/lib.rs b/leptos_dom/src/lib.rs index e2a494763..419677b08 100644 --- a/leptos_dom/src/lib.rs +++ b/leptos_dom/src/lib.rs @@ -542,8 +542,19 @@ impl View { pub fn on( self, event: E, - event_handler: impl FnMut(E::EventType) + 'static, + mut event_handler: impl FnMut(E::EventType) + 'static, ) -> Self { + cfg_if::cfg_if! { + if #[cfg(debug_assertions)] { + trace!("calling on() {}", event.name()); + let span = ::tracing::Span::current(); + let event_handler = move |e| { + let _guard = span.enter(); + event_handler(e); + }; + } + } + self.on_impl(event, Box::new(event_handler)) } From 808d87598babb63d2ff253d294489659d88b766c Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 16:20:00 -0500 Subject: [PATCH 04/10] Tracing for events and elements. --- leptos_dom/src/html.rs | 63 ++++++++++++++++++++++++++---------------- leptos_dom/src/lib.rs | 7 ++++- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/leptos_dom/src/html.rs b/leptos_dom/src/html.rs index 2349c9202..bbe7735f1 100644 --- a/leptos_dom/src/html.rs +++ b/leptos_dom/src/html.rs @@ -90,7 +90,12 @@ where element: el, }; - HtmlElement { cx, element } + HtmlElement { + cx, + element, + #[cfg(debug_assertions)] + span: ::tracing::Span::current() + } } #[cfg(not(all(target_arch = "wasm32", feature = "web")))] @@ -192,6 +197,8 @@ cfg_if! { /// Represents an HTML element. #[derive(Clone)] pub struct HtmlElement { + #[cfg(debug_assertions)] + pub(crate) span: ::tracing::Span, pub(crate) cx: Scope, pub(crate) element: El, } @@ -236,6 +243,8 @@ impl HtmlElement { Self { cx, element, + #[cfg(debug_assertions)] + span: ::tracing::Span::current() } } else { Self { @@ -272,6 +281,8 @@ impl HtmlElement { let Self { cx, element, + #[cfg(debug_assertions)] + span } = self; HtmlElement { @@ -281,6 +292,8 @@ impl HtmlElement { element: element.as_ref().clone(), is_void: element.is_void(), }, + #[cfg(debug_assertions)] + span } } else { let Self { @@ -568,19 +581,6 @@ impl HtmlElement { /// Adds an event listener to this element. #[track_caller] - #[cfg_attr( - debug_assertions, - instrument( - level = "trace", - name = "event handler", - skip_all, - fields( - tag = %self.element.name(), - event = %event.name(), - defined_at = %std::panic::Location::caller() - ) - ) - )] pub fn on( self, event: E, @@ -589,17 +589,19 @@ impl HtmlElement { ) -> Self { #[cfg(all(target_arch = "wasm32", feature = "web"))] { - let event_name = event.name(); - - cfg_if::cfg_if! { - if #[cfg(debug_assertions)] { - let span = ::tracing::Span::current(); - let event_handler = move |e| { - let _guard = span.enter(); - event_handler(e); - }; + cfg_if! { + if #[cfg(debug_assertions)] { + let span = self.span.clone(); + let onspan = ::tracing::span!( + parent: &self.span, + ::tracing::Level::TRACE, + "on", + event = %event.name() + ); + let _onguard = onspan.enter(); + } } - } + let event_name = event.name(); if event.bubbles() { add_event_listener(self.element.as_ref(), event_name, event_handler); @@ -889,7 +891,20 @@ macro_rules! generate_html_tags { } #[$meta] + #[cfg_attr( + debug_assertions, + instrument( + level = "trace", + name = "HtmlElement", + skip_all, + fields( + tag = %format!("<{}/>", stringify!($tag)) + ) + ) + )] pub fn $tag(cx: Scope) -> HtmlElement<[<$tag:camel $($trailing_)?>]> { + #[cfg(debug_assertions)] + trace!("creating <{}/>", stringify!($tag)); HtmlElement::new(cx, [<$tag:camel $($trailing_)?>]::default()) } )* diff --git a/leptos_dom/src/lib.rs b/leptos_dom/src/lib.rs index 419677b08..f740b1e70 100644 --- a/leptos_dom/src/lib.rs +++ b/leptos_dom/src/lib.rs @@ -206,7 +206,12 @@ impl Element { is_void: false, }; - HtmlElement { cx, element } + HtmlElement { + cx, + element, + #[cfg(debug_assertions)] + span: ::tracing::Span::current() + } } #[cfg(not(all(target_arch = "wasm32", feature = "web")))] From 063b946cd415135925bd07fde79b9b063d48bed5 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 16:27:25 -0500 Subject: [PATCH 05/10] Remove unnecessary log --- leptos_dom/src/html.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/leptos_dom/src/html.rs b/leptos_dom/src/html.rs index bbe7735f1..f31d22384 100644 --- a/leptos_dom/src/html.rs +++ b/leptos_dom/src/html.rs @@ -903,8 +903,6 @@ macro_rules! generate_html_tags { ) )] pub fn $tag(cx: Scope) -> HtmlElement<[<$tag:camel $($trailing_)?>]> { - #[cfg(debug_assertions)] - trace!("creating <{}/>", stringify!($tag)); HtmlElement::new(cx, [<$tag:camel $($trailing_)?>]::default()) } )* From f2842cf14ee20d06929eadd4e34c554b6e283222 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Sat, 7 Jan 2023 17:04:58 -0500 Subject: [PATCH 06/10] `children` should take `FnOnce(Scope) -> Fragment`, to ease need of cloning etc. --- leptos/src/suspense.rs | 26 +++++++++++++------------- leptos/src/transition.rs | 8 ++++---- leptos_macro/src/lib.rs | 4 ++-- router/src/components/form.rs | 6 +++--- router/src/components/link.rs | 2 +- router/src/components/route.rs | 2 +- router/src/components/router.rs | 6 +++--- router/src/components/routes.rs | 2 +- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/leptos/src/suspense.rs b/leptos/src/suspense.rs index e6e066a5d..03aa758dd 100644 --- a/leptos/src/suspense.rs +++ b/leptos/src/suspense.rs @@ -1,10 +1,10 @@ use cfg_if::cfg_if; -use leptos_macro::component; -use std::rc::Rc; -use leptos_dom::{DynChild, Fragment, IntoView, Component}; -use leptos_reactive::{provide_context, Scope, SuspenseContext}; +use leptos_dom::{Component, DynChild, Fragment, IntoView}; #[cfg(not(any(feature = "csr", feature = "hydrate")))] use leptos_dom::{HydrationCtx, HydrationKey}; +use leptos_macro::component; +use leptos_reactive::{provide_context, Scope, SuspenseContext}; +use std::rc::Rc; /// If any [Resources](leptos_reactive::Resource) are read in the `children` of this /// component, it will show the `fallback` while they are loading. Once all are resolved, @@ -58,7 +58,7 @@ pub fn Suspense( /// Returns a fallback UI that will be shown while `async` [Resources](leptos_reactive::Resource) are still loading. fallback: F, /// Children will be displayed once all `async` [Resources](leptos_reactive::Resource) have resolved. - children: Box Fragment>, + children: Box Fragment>, ) -> impl IntoView where F: Fn() -> E + 'static, @@ -88,8 +88,8 @@ where } else { // run the child; we'll probably throw this away, but it will register resource reads let child = orig_child(cx).into_view(cx); - - let initial = { + + let initial = { // no resources were read under this, so just return the child if context.pending_resources.get() == 0 { child.clone() @@ -97,10 +97,10 @@ where // show the fallback, but also prepare to stream HTML else { let orig_child = Rc::clone(&orig_child); - + cx.register_suspense( context, - &id_before_suspense.to_string(), + &id_before_suspense.to_string(), ¤t_id.to_string(), { let current_id = current_id.clone(); @@ -117,17 +117,17 @@ where } } ); - + // return the fallback for now, wrapped in fragment identifer fallback().into_view(cx) } }; - + HydrationCtx::continue_from(current_id.clone()); - + initial } } }) }) -} \ No newline at end of file +} diff --git a/leptos/src/transition.rs b/leptos/src/transition.rs index 8223c0173..87d2dad00 100644 --- a/leptos/src/transition.rs +++ b/leptos/src/transition.rs @@ -1,6 +1,6 @@ use leptos_dom::{Fragment, IntoView, View}; use leptos_macro::component; -use leptos_reactive::{ Scope, SignalSetter}; +use leptos_reactive::{Scope, SignalSetter}; use std::{cell::RefCell, rc::Rc}; /// If any [Resource](leptos_reactive::Resource)s are read in the `children` of this @@ -66,7 +66,7 @@ pub fn Transition( #[prop(optional)] set_pending: Option>, /// Will be displayed once all resources have resolved. - children: Box Fragment> + children: Box Fragment>, ) -> impl IntoView where F: Fn() -> E + 'static, @@ -98,6 +98,6 @@ where } frag })) - .build() + .build(), ) -} \ No newline at end of file +} diff --git a/leptos_macro/src/lib.rs b/leptos_macro/src/lib.rs index 583faaf27..c5fbc6c79 100644 --- a/leptos_macro/src/lib.rs +++ b/leptos_macro/src/lib.rs @@ -358,12 +358,12 @@ pub fn view(tokens: TokenStream) -> TokenStream { /// ``` /// /// 5. You can access the children passed into the component with the `children` property, which takes -/// an argument of the form `Box Fragment>`. +/// an argument of the form `Box Fragment>`. /// /// ``` /// # use leptos::*; /// #[component] -/// fn ComponentWithChildren(cx: Scope, children: Box Fragment>) -> impl IntoView { +/// fn ComponentWithChildren(cx: Scope, children: Box Fragment>) -> impl IntoView { /// view! { /// cx, ///