AI: create a macro that measurements the performance of a component
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -1685,6 +1685,7 @@ name = "glimmer-yew"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"derive_builder",
|
||||
"glimmer-yew-macros",
|
||||
"gloo-console 0.3.0",
|
||||
"gloo-timers 0.3.0",
|
||||
"lazy_static",
|
||||
@@ -1695,6 +1696,15 @@ dependencies = [
|
||||
"yew-router",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glimmer-yew-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gloo"
|
||||
version = "0.8.1"
|
||||
|
||||
@@ -37,7 +37,7 @@ members = [
|
||||
"visions/server",
|
||||
# "visions/types",
|
||||
"visions/ui",
|
||||
"visions/core", "glimmer/yew", "utils",
|
||||
"visions/core", "glimmer/yew", "glimmer/yew-macros", "utils",
|
||||
# "bike-lights/bike",
|
||||
]
|
||||
|
||||
|
||||
12
glimmer/yew-macros/Cargo.toml
Normal file
12
glimmer/yew-macros/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "glimmer-yew-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2", features = ["full"] }
|
||||
37
glimmer/yew-macros/src/lib.rs
Normal file
37
glimmer/yew-macros/src/lib.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{ItemFn, parse_macro_input};
|
||||
|
||||
/// Wraps a Yew function component's body with wall-time performance measurement.
|
||||
///
|
||||
/// Captures the time before and after the component function executes and logs
|
||||
/// the duration via `gloo_console`. Apply it above `#[function_component]` so
|
||||
/// the timing wraps the raw function before Yew transforms it.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// #[measured]
|
||||
/// #[function_component]
|
||||
/// fn MyComponent(props: &MyProps) -> Html {
|
||||
/// html! { <div /> }
|
||||
/// }
|
||||
/// ```
|
||||
/// Emits: `[PERF] MyComponent: 0.123ms`
|
||||
#[proc_macro_attribute]
|
||||
pub fn measured(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut func = parse_macro_input!(item as ItemFn);
|
||||
let fn_name = func.sig.ident.to_string();
|
||||
let stmts = func.block.stmts.clone();
|
||||
|
||||
let new_block = syn::parse_quote! {
|
||||
{
|
||||
let __measured_t0 = ::glimmer_yew::__measured_start();
|
||||
let __measured_result = { #(#stmts)* };
|
||||
::glimmer_yew::__measured_end(#fn_name, __measured_t0);
|
||||
__measured_result
|
||||
}
|
||||
};
|
||||
|
||||
func.block = Box::new(new_block);
|
||||
quote! { #func }.into()
|
||||
}
|
||||
@@ -4,11 +4,12 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
glimmer-yew-macros = { path = "../yew-macros" }
|
||||
stylist = { workspace = true, features = ["yew", "yew_integration"] }
|
||||
yew.workspace = true
|
||||
lazy_static.workspace = true
|
||||
wasm-bindgen-futures.workspace = true
|
||||
web-sys = { workspace = true, features = ["HtmlDialogElement"] }
|
||||
web-sys = { workspace = true, features = ["HtmlDialogElement", "Performance", "Window"] }
|
||||
gloo-timers = { version = "0.3.0", features = ["futures"] }
|
||||
yew-router.workspace = true
|
||||
gloo-console.workspace = true
|
||||
|
||||
@@ -9,6 +9,7 @@ mod label;
|
||||
mod list;
|
||||
mod macros;
|
||||
mod modal;
|
||||
pub use glimmer_yew_macros::measured;
|
||||
mod panel;
|
||||
mod range;
|
||||
mod row;
|
||||
@@ -20,10 +21,13 @@ mod tabbed_view;
|
||||
mod text_entry;
|
||||
mod utils;
|
||||
|
||||
pub use utils::{__measured_end, __measured_start};
|
||||
|
||||
pub mod prelude {
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
|
||||
pub use crate::{
|
||||
measured,
|
||||
adjustable_value_field::AdjustableValueField,
|
||||
button::{Button, ButtonVariant, Toggle},
|
||||
button_group::ButtonGroup,
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
#[doc(hidden)]
|
||||
pub fn __measured_start() -> f64 {
|
||||
web_sys::window()
|
||||
.and_then(|w| w.performance())
|
||||
.map_or(0.0, |p| p.now())
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn __measured_end(name: &str, start: f64) {
|
||||
let end = web_sys::window()
|
||||
.and_then(|w| w.performance())
|
||||
.map_or(start, |p| p.now());
|
||||
gloo_console::log!(format!("[PERF] {}: {:.3}ms", name, end - start));
|
||||
}
|
||||
|
||||
pub fn navigate_to(path: &str) {
|
||||
match web_sys::window() {
|
||||
Some(window) => {
|
||||
|
||||
Reference in New Issue
Block a user