diff --git a/.cargo/config b/.cargo/config deleted file mode 100644 index 4ec2f3b..0000000 --- a/.cargo/config +++ /dev/null @@ -1,2 +0,0 @@ -[target.wasm32-unknown-unknown] -runner = 'wasm-bindgen-test-runner' diff --git a/.github/workflows/everything.yml b/.github/workflows/everything.yml index 3582435..65ac8fc 100644 --- a/.github/workflows/everything.yml +++ b/.github/workflows/everything.yml @@ -72,6 +72,36 @@ jobs: - name: Run Browser Tests run: wasm-pack test --headless --chrome --firefox examples/yew-integration + - name: Run Browser Benchmarks + run: wasm-pack test --headless --chrome --firefox ci/benchmarks --release --no-default-features + + - name: "Run Codesize Benchmark: Macros" + working-directory: ci/codesize + env: + TRUNK_BUILD_TARGET: index.macros.html + run: | + trunk build --release + gzip -r --best dist + gzip -r --list dist + + - name: "Run Codesize Benchmark: Parser" + working-directory: ci/codesize + env: + TRUNK_BUILD_TARGET: index.parser.html + run: | + trunk build --release + gzip -r --best dist + gzip -r --list dist + + - name: "Run Codesize Benchmark: Yew Integration" + working-directory: ci/codesize + env: + TRUNK_BUILD_TARGET: index.yew_integration.html + run: | + trunk build --release + gzip -r --best dist + gzip -r --list dist + publish: name: Publish to crates.io runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index a4cc4c4..806edf1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,15 @@ members = [ "packages/stylist-core", "packages/stylist-macros", - "examples/benchmarks", "examples/yew-proc-macros", "examples/yew-integration", "examples/yew-shadow", "examples/yew-theme-context", "examples/yew-theme-hooks", "examples/use-media-query", + + "ci/benchmarks", + "ci/codesize", ] resolver = "2" diff --git a/Trunk.toml b/Trunk.toml index a854b99..6f97a50 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -7,9 +7,11 @@ ignore = [ "packages/stylist/target/", "packages/stylist-core/target/", - "examples/benchmarks/target/", "examples/yew-integration/target/", "examples/yew-theme-context/target/", + + "ci/benchmarks/target/", + "ci/codesize/target/", ] [tools] diff --git a/ci/benchmarks/Cargo.toml b/ci/benchmarks/Cargo.toml new file mode 100644 index 0000000..9743fbc --- /dev/null +++ b/ci/benchmarks/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "stylist-benchmarks" +version = "0.1.0" +authors = ["Kaede Hoshikawa "] +edition = "2018" + +[dependencies] +stylist = { path = "../../packages/stylist" } + +log = "0.4.14" +console_log = { version = "0.2.0", features = ["color"] } +web-sys = { version = "0.3.54", features = [ + "Window", + "Performance", +] } + +yew = { git = "https://github.com/yewstack/yew", optional = true } +gloo = { version = "0.3.0", optional = true } + +[features] +default = ["with_interface"] +with_interface = ["stylist/yew_integration", "yew", "gloo"] + +[dev-dependencies] +wasm-bindgen-test = "0.3.26" +wasm-bindgen = "0.2" diff --git a/examples/benchmarks/README.md b/ci/benchmarks/README.md similarity index 100% rename from examples/benchmarks/README.md rename to ci/benchmarks/README.md diff --git a/examples/benchmarks/index.html b/ci/benchmarks/index.html similarity index 100% rename from examples/benchmarks/index.html rename to ci/benchmarks/index.html diff --git a/ci/benchmarks/src/app.rs b/ci/benchmarks/src/app.rs new file mode 100644 index 0000000..17cf3a2 --- /dev/null +++ b/ci/benchmarks/src/app.rs @@ -0,0 +1,265 @@ +use gloo::timers::callback::Timeout; +use stylist::yew::Global; +use stylist::{StyleSource, YieldStyle}; +use yew::prelude::*; + +use crate::runner::BenchmarkResults; + +static GLOBAL_STYLE: &str = r#" + html, body { + margin: 0; + padding: 0; + font-family: sans-serif; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + } +"#; + +pub enum BenchMsg { + Step(BenchmarkResults), +} + +pub struct Benchmarks { + finished: bool, + results: BenchmarkResults, +} + +impl Benchmarks { + fn step(&mut self, ctx: &Context) { + let link = ctx.link(); + let mut results = self.results.clone(); + let cb = link.batch_callback_once(move |_| results.step().then(|| BenchMsg::Step(results))); + Timeout::new(0, move || cb.emit(())).forget(); + } +} + +impl Component for Benchmarks { + type Message = BenchMsg; + type Properties = (); + + fn create(_: &Context) -> Self { + Self { + finished: false, + results: Default::default(), + } + } + + fn rendered(&mut self, ctx: &Context, first_render: bool) { + if first_render { + self.step(ctx); + } + } + + fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { + match msg { + Self::Message::Step(next_results) => { + self.results = next_results; + self.step(ctx); + } + } + true + } + + fn changed(&mut self, _: &Context) -> bool { + false + } + + fn view(&self, _: &Context) -> Html { + let results = &self.results; + html! { +
+ { + if !self.finished { + html!{
{"Benchmarking..."}
{"The browser may be unresponsive during the benchmark."}
} + } else { + html!{
} + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{"Benchmark"}{"Result"}
{"Parse Simple (10,000,000 iterations): "}{results.parse_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Literal) Simple (10,000,000 iterations): "}{results.macro_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Inline) Simple (10,000,000 iterations): "}{results.macro_inline_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Simple, No Cache (100,000 iterations): "}{results.parse_simple_no_cache.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Complex (1,000,000 iterations): "}{results.parse_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Literal) Complex (1,000,000 iterations): "}{results.macro_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Inline) Complex (1,000,000 iterations): "}{results.macro_inline_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Complex, No Cache (100,000 iterations): "}{results.parse_complex_no_cache.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Cached Lookup (1,000,000 iterations): "}{results.cached_lookup.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Cached Lookup, Big Sheet (100,000 iterations): "}{results.cached_lookup_big_sheet.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Mounting (2,000 iterations): "}{results.mounting.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
+
+ } + } +} + +impl YieldStyle for Benchmarks { + fn style_from(&self) -> StyleSource<'static> { + r#" + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + .running { + height: 50px; + } + + table { + border: 1px solid black; + border-collapse: collapse; + } + + thead { + font-weight: bold; + background-color: rgb(240, 240, 240); + } + + th { + text-align: left; + border: 1px solid black; + border-collapse: collapse; + padding: 5px; + } + + tbody th { + font-weight: normal; + } + + th:nth-child(1) { + padding-right: 20px; + } + + th:nth-child(2) { + padding-left: 20px; + padding-right: 20px; + } + + tbody tr:nth-child(even) { + background-color: rgb(240, 240, 240); + } + "# + .into() + } +} + +#[derive(Debug, PartialEq)] +pub enum AppMsg { + Start, +} + +pub struct App { + started: bool, +} + +impl Component for App { + type Message = AppMsg; + type Properties = (); + + fn create(_: &Context) -> Self { + Self { started: false } + } + + fn update(&mut self, _: &Context, msg: Self::Message) -> bool { + assert_eq!(msg, AppMsg::Start); + + self.started = true; + + true + } + + fn changed(&mut self, _: &Context) -> bool { + false + } + + fn view(&self, ctx: &Context) -> Html { + html! { + <> + +
+

{"Stylist Benchmark"}

+ { + if self.started { + html!{} + } else { + html!{ + <> +
{"To start benchmarking, please click start:"}
+ + + } + } + } +
+ + } + } +} + +impl YieldStyle for App { + fn style_from(&self) -> StyleSource<'static> { + r#" + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + .before-intro { + padding-bottom: 20px; + } + + button { + width: 300px; + height: 50px; + font-size: 20px; + } + "# + .into() + } +} diff --git a/examples/benchmarks/src/benchmarks.rs b/ci/benchmarks/src/benchmarks.rs similarity index 100% rename from examples/benchmarks/src/benchmarks.rs rename to ci/benchmarks/src/benchmarks.rs diff --git a/ci/benchmarks/src/main.rs b/ci/benchmarks/src/main.rs new file mode 100644 index 0000000..9adadca --- /dev/null +++ b/ci/benchmarks/src/main.rs @@ -0,0 +1,45 @@ +#[cfg(feature = "with_interface")] +mod app; +mod benchmarks; +mod runner; +mod utils; + +#[cfg(feature = "with_interface")] +fn main() { + use crate::app::App; + use log::Level; + + console_log::init_with_level(Level::Trace).expect("Failed to initialise Log!"); + yew::start_app::(); +} + +#[cfg(not(feature = "with_interface"))] +fn main() { + use crate::runner::BenchmarkResults; + use log::Level; + + console_log::init_with_level(Level::Info).expect("Failed to initialize Log!"); + let mut results = BenchmarkResults::default(); + while !results.step() {} + + log::info!("Benchmarks results: {:#?}", results); +} + +#[cfg(test)] +mod tests { + use crate::runner::BenchmarkResults; + use log::Level; + use wasm_bindgen_test::*; + + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + + #[wasm_bindgen_test] + fn benchmark_runner() { + console_log::init_with_level(Level::Debug).expect(""); + + let mut results = BenchmarkResults::default(); + while results.step() {} + + log::debug!("Benchmarks results: {:#?}", results); + } +} diff --git a/ci/benchmarks/src/runner.rs b/ci/benchmarks/src/runner.rs new file mode 100644 index 0000000..ffc6110 --- /dev/null +++ b/ci/benchmarks/src/runner.rs @@ -0,0 +1,59 @@ +use crate::benchmarks; + +#[derive(Default, Clone, Debug)] +pub struct BenchmarkResults { + pub parse_simple: Option, + pub macro_simple: Option, + pub macro_inline_simple: Option, + pub parse_simple_no_cache: Option, + pub parse_complex: Option, + pub macro_complex: Option, + pub macro_inline_complex: Option, + pub parse_complex_no_cache: Option, + + pub cached_lookup: Option, + pub cached_lookup_big_sheet: Option, + + pub mounting: Option, +} + +impl BenchmarkResults { + pub fn step(&mut self) -> bool { + if self.parse_simple.is_none() { + self.parse_simple = Some(benchmarks::bench_parse_simple()); + true + } else if self.macro_simple.is_none() { + self.macro_simple = Some(benchmarks::bench_macro_simple()); + true + } else if self.macro_inline_simple.is_none() { + self.macro_inline_simple = Some(benchmarks::bench_macro_inline_simple()); + true + } else if self.parse_simple_no_cache.is_none() { + self.parse_simple_no_cache = Some(benchmarks::bench_parse_simple_no_cache()); + true + } else if self.parse_complex.is_none() { + self.parse_complex = Some(benchmarks::bench_parse_complex()); + true + } else if self.macro_complex.is_none() { + self.macro_complex = Some(benchmarks::bench_macro_complex()); + true + } else if self.macro_inline_complex.is_none() { + self.macro_inline_complex = Some(benchmarks::bench_macro_inline_complex()); + true + } else if self.parse_complex_no_cache.is_none() { + self.parse_complex_no_cache = Some(benchmarks::bench_parse_complex_no_cache()); + true + } else if self.cached_lookup.is_none() { + self.cached_lookup = Some(benchmarks::bench_cached_lookup()); + true + } else if self.cached_lookup_big_sheet.is_none() { + self.cached_lookup_big_sheet = Some(benchmarks::bench_cached_lookup_big_sheet()); + true + } else if self.mounting.is_none() { + self.mounting = Some(benchmarks::bench_mounting()); + true + } else { + false + } + } +} diff --git a/examples/benchmarks/src/utils.rs b/ci/benchmarks/src/utils.rs similarity index 100% rename from examples/benchmarks/src/utils.rs rename to ci/benchmarks/src/utils.rs diff --git a/ci/codesize/Cargo.toml b/ci/codesize/Cargo.toml new file mode 100644 index 0000000..503a9c5 --- /dev/null +++ b/ci/codesize/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "stylist-codesize" +version = "0.1.0" +authors = ["Kaede Hoshikawa "] +edition = "2018" + +[dependencies] +stylist = { path = "../../packages/stylist", default-features = false } +yew = { git = "https://github.com/yewstack/yew", optional = true } + +[features] +default = [] +macros = ["stylist/macros"] +yew_integration = ["stylist/yew_integration", "yew"] +parser = ["stylist/parser"] +random = ["stylist/random"] diff --git a/ci/codesize/README.md b/ci/codesize/README.md new file mode 100644 index 0000000..b02297a --- /dev/null +++ b/ci/codesize/README.md @@ -0,0 +1,3 @@ +# Stylist Codesize + +Measures code size of stylist under a few common use profiles. diff --git a/ci/codesize/index.macros.html b/ci/codesize/index.macros.html new file mode 100644 index 0000000..d5f760d --- /dev/null +++ b/ci/codesize/index.macros.html @@ -0,0 +1,13 @@ + + + + + Stylist Benchmarks + + + diff --git a/ci/codesize/index.parser.html b/ci/codesize/index.parser.html new file mode 100644 index 0000000..c2bd4f2 --- /dev/null +++ b/ci/codesize/index.parser.html @@ -0,0 +1,13 @@ + + + + + Stylist Benchmarks + + + diff --git a/ci/codesize/index.yew_integration.html b/ci/codesize/index.yew_integration.html new file mode 100644 index 0000000..f3f3a79 --- /dev/null +++ b/ci/codesize/index.yew_integration.html @@ -0,0 +1,13 @@ + + + + + Stylist Benchmarks + + + diff --git a/ci/codesize/src/macro_uses.rs b/ci/codesize/src/macro_uses.rs new file mode 100644 index 0000000..d8c0b31 --- /dev/null +++ b/ci/codesize/src/macro_uses.rs @@ -0,0 +1,89 @@ +use stylist::ast::{sheet, Sheet}; +use stylist::Style; + +fn use_simple_sheet() { + let sheet: Sheet = sheet!("color:red;"); + Style::new(sheet).unwrap(); +} + +fn use_macro_inline_simple() { + let sheet: Sheet = sheet!(color:red;); + Style::new(sheet).unwrap(); +} + +fn use_macro_complex() { + let i = 513; + let sheet: Sheet = sheet!( + r#" + color:red; + + .class-name-a { + background: red; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + @media screen and (max-width: ${i}px;) { + font-size: 0.9rem; + + .class-name-b { + flex-direction: row; + } + } + "#, + i = i / 1000 + ); + Style::new(sheet).unwrap(); +} + +fn use_macro_inline_complex() { + let i = 1_000_101; + let sheet: Sheet = sheet!( + color: red; + + .class-name-a { + background: red; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + @media screen and (max-width: ${i / 1000}px;) { + font-size: 0.9rem; + + .class-name-b { + flex-direction: row; + } + } + ); + Style::new(sheet).unwrap(); +} + +fn use_large_sheets() { + let snippet = sheet!("color:red;"); + let mut sheet_parts = vec![]; + let mut sheets = vec![]; + + for _ in 1..100 { + sheet_parts.extend_from_slice(&snippet); + let sheet: Sheet = Sheet::from(sheet_parts.clone()); + sheets.push(sheet); + } + + for sheet in sheets { + Style::new(sheet).expect("Failed to mount stylesheet."); + } +} + +pub fn use_stylist() { + use_simple_sheet(); + use_macro_inline_simple(); + use_macro_complex(); + use_macro_inline_complex(); + use_large_sheets(); +} diff --git a/ci/codesize/src/main.rs b/ci/codesize/src/main.rs new file mode 100644 index 0000000..7f20c31 --- /dev/null +++ b/ci/codesize/src/main.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "macros")] +mod macro_uses; +#[cfg(feature = "parser")] +mod parser_uses; +#[cfg(feature = "yew_integration")] +mod yew_uses; + +fn main() { + #[cfg(feature = "macros")] + macro_uses::use_stylist(); + #[cfg(feature = "yew_integration")] + yew_uses::use_stylist(); + #[cfg(feature = "parser")] + parser_uses::use_stylist(); +} diff --git a/ci/codesize/src/parser_uses.rs b/ci/codesize/src/parser_uses.rs new file mode 100644 index 0000000..af10be2 --- /dev/null +++ b/ci/codesize/src/parser_uses.rs @@ -0,0 +1,18 @@ +use stylist::Style; + +fn basic_parsing() { + Style::new( + r#" + background-color: red; + .nested { + background-color: blue; + width: 100px + } + "#, + ) + .expect("Failed to create style"); +} + +pub fn use_stylist() { + basic_parsing(); +} diff --git a/ci/codesize/src/yew_uses.rs b/ci/codesize/src/yew_uses.rs new file mode 100644 index 0000000..cc69dec --- /dev/null +++ b/ci/codesize/src/yew_uses.rs @@ -0,0 +1,72 @@ +use stylist::yew::{styled_component, Global}; +use yew::prelude::*; + +#[styled_component(Inside)] +fn inside() -> Html { + html! { +
+ {"The quick brown fox jumps over the lazy dog"} +
+ } +} + +#[styled_component(App)] +fn app() -> Html { + html! { + <> + // Global Styles can be applied with component. + +

{"Yew Integration"}

+
+ {"The quick brown fox jumps over the lazy dog"} + +
+ + } +} + +pub fn use_stylist() { + yew::start_app::(); +} diff --git a/examples/benchmarks/Cargo.toml b/examples/benchmarks/Cargo.toml deleted file mode 100644 index 157f7eb..0000000 --- a/examples/benchmarks/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "stylist-benchmarks" -version = "0.1.0" -authors = ["Kaede Hoshikawa "] -edition = "2018" - -[dependencies] -log = "0.4.14" -console_log = { version = "0.2.0", features = ["color"] } -yew = { git = "https://github.com/yewstack/yew" } -stylist = { path = "../../packages/stylist", features = ["yew_integration"] } -web-sys = { version = "0.3.54", features = [ - "Window", - "Performance", -] } -gloo = "0.3.0" diff --git a/examples/benchmarks/src/main.rs b/examples/benchmarks/src/main.rs deleted file mode 100644 index 6f3748a..0000000 --- a/examples/benchmarks/src/main.rs +++ /dev/null @@ -1,384 +0,0 @@ -use gloo::timers::callback::Timeout; -use stylist::yew::Global; -use stylist::{StyleSource, YieldStyle}; -use yew::prelude::*; - -use log::Level; - -mod benchmarks; -mod utils; - -static GLOBAL_STYLE: &str = r#" - html, body { - margin: 0; - padding: 0; - font-family: sans-serif; - display: flex; - justify-content: center; - flex-direction: column; - align-items: center; - } -"#; - -pub enum BenchMsg { - ParseSimpleFinish(f64), - MacroSimpleFinish(f64), - MacroInlineSimpleFinish(f64), - ParseSimpleNoCacheFinish(f64), - ParseComplexFinish(f64), - MacroComplexFinish(f64), - MacroInlineComplexFinish(f64), - ParseComplexNoCacheFinish(f64), - CachedLookupFinish(f64), - CachedLookupBigSheetFinish(f64), - MountingFinish(f64), -} - -pub struct Benchmarks { - finished: bool, - - parse_simple: Option, - macro_simple: Option, - macro_inline_simple: Option, - parse_simple_no_cache: Option, - parse_complex: Option, - macro_complex: Option, - macro_inline_complex: Option, - parse_complex_no_cache: Option, - - cached_lookup: Option, - cached_lookup_big_sheet: Option, - - mounting: Option, -} - -impl Component for Benchmarks { - type Message = BenchMsg; - type Properties = (); - - fn create(_ctx: &Context) -> Self { - Self { - finished: false, - parse_simple: None, - macro_simple: None, - macro_inline_simple: None, - parse_simple_no_cache: None, - parse_complex: None, - macro_complex: None, - macro_inline_complex: None, - parse_complex_no_cache: None, - cached_lookup: None, - cached_lookup_big_sheet: None, - mounting: None, - } - } - - fn rendered(&mut self, ctx: &Context, first_render: bool) { - if first_render { - let cb = ctx - .link() - .callback(|_| BenchMsg::ParseSimpleFinish(benchmarks::bench_parse_simple())); - Timeout::new(100, move || cb.emit(())).forget(); - } - } - - fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { - match msg { - BenchMsg::ParseSimpleFinish(m) => { - self.parse_simple = Some(m); - let cb = ctx - .link() - .callback(|_| BenchMsg::MacroSimpleFinish(benchmarks::bench_macro_simple())); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::MacroSimpleFinish(m) => { - self.macro_simple = Some(m); - let cb = ctx.link().callback(|_| { - BenchMsg::MacroInlineSimpleFinish(benchmarks::bench_macro_inline_simple()) - }); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::MacroInlineSimpleFinish(m) => { - self.macro_inline_simple = Some(m); - let cb = ctx.link().callback(|_| { - BenchMsg::ParseSimpleNoCacheFinish(benchmarks::bench_parse_simple_no_cache()) - }); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::ParseSimpleNoCacheFinish(m) => { - self.parse_simple_no_cache = Some(m); - let cb = ctx - .link() - .callback(|_| BenchMsg::ParseComplexFinish(benchmarks::bench_parse_complex())); - - Timeout::new(100, move || cb.emit(())).forget(); - } - - BenchMsg::ParseComplexFinish(m) => { - self.parse_complex = Some(m); - - let cb = ctx - .link() - .callback(|_| BenchMsg::MacroComplexFinish(benchmarks::bench_macro_complex())); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::MacroComplexFinish(m) => { - self.macro_complex = Some(m); - - let cb = ctx.link().callback(|_| { - BenchMsg::MacroInlineComplexFinish(benchmarks::bench_macro_inline_complex()) - }); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::MacroInlineComplexFinish(m) => { - self.macro_inline_complex = Some(m); - - let cb = ctx.link().callback(|_| { - BenchMsg::ParseComplexNoCacheFinish(benchmarks::bench_parse_complex_no_cache()) - }); - - Timeout::new(100, move || cb.emit(())).forget(); - } - BenchMsg::ParseComplexNoCacheFinish(m) => { - self.parse_complex_no_cache = Some(m); - - let cb = ctx - .link() - .callback(|_| BenchMsg::CachedLookupFinish(benchmarks::bench_cached_lookup())); - - Timeout::new(100, move || cb.emit(())).forget(); - } - - BenchMsg::CachedLookupFinish(m) => { - self.cached_lookup = Some(m); - - let cb = - ctx.link().callback(|_| { - BenchMsg::CachedLookupBigSheetFinish( - benchmarks::bench_cached_lookup_big_sheet(), - ) - }); - - Timeout::new(100, move || cb.emit(())).forget(); - } - - BenchMsg::CachedLookupBigSheetFinish(m) => { - self.cached_lookup_big_sheet = Some(m); - - let cb = ctx - .link() - .callback(|_| BenchMsg::MountingFinish(benchmarks::bench_mounting())); - - Timeout::new(100, move || cb.emit(())).forget(); - } - - BenchMsg::MountingFinish(m) => { - self.mounting = Some(m); - self.finished = true; - } - } - true - } - - fn view(&self, _ctx: &Context) -> Html { - html! { -
- { - if !self.finished { - html!{
{"Benchmarking..."}
{"The browser may be unresponsive during the benchmark."}
} - } else { - html!{
} - } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{"Benchmark"}{"Result"}
{"Parse Simple (10,000,000 iterations): "}{self.parse_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Literal) Simple (10,000,000 iterations): "}{self.macro_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Inline) Simple (10,000,000 iterations): "}{self.macro_inline_simple.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Simple, No Cache (100,000 iterations): "}{self.parse_simple_no_cache.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Complex (1,000,000 iterations): "}{self.parse_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Literal) Complex (1,000,000 iterations): "}{self.macro_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Macro (Inline) Complex (1,000,000 iterations): "}{self.macro_inline_complex.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Parse Complex, No Cache (100,000 iterations): "}{self.parse_complex_no_cache.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Cached Lookup (1,000,000 iterations): "}{self.cached_lookup.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Cached Lookup, Big Sheet (100,000 iterations): "}{self.cached_lookup_big_sheet.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
{"Mounting (2,000 iterations): "}{self.mounting.map(|m| {format!("{:.0}ms", m)}).unwrap_or_else(|| "".to_string())}
-
- } - } -} - -impl YieldStyle for Benchmarks { - fn style_from(&self) -> StyleSource<'static> { - r#" - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - - .running { - height: 50px; - } - - table { - border: 1px solid black; - border-collapse: collapse; - } - - thead { - font-weight: bold; - background-color: rgb(240, 240, 240); - } - - th { - text-align: left; - border: 1px solid black; - border-collapse: collapse; - padding: 5px; - } - - tbody th { - font-weight: normal; - } - - th:nth-child(1) { - padding-right: 20px; - } - - th:nth-child(2) { - padding-left: 20px; - padding-right: 20px; - } - - tbody tr:nth-child(even) { - background-color: rgb(240, 240, 240); - } - "# - .into() - } -} - -#[derive(Debug, PartialEq)] -pub enum AppMsg { - Start, -} - -pub struct App { - started: bool, -} - -impl Component for App { - type Message = AppMsg; - type Properties = (); - - fn create(_ctx: &Context) -> Self { - Self { started: false } - } - - fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { - assert_eq!(msg, AppMsg::Start); - - self.started = true; - - true - } - - fn view(&self, ctx: &Context) -> Html { - html! { - <> - -
-

{"Stylist Benchmark"}

- { - if self.started { - html!{} - } else { - html!{ - <> -
{"To start benchmarking, please click start:"}
- - - } - } - } -
- - } - } -} - -impl YieldStyle for App { - fn style_from(&self) -> StyleSource<'static> { - r#" - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - - .before-intro { - padding-bottom: 20px; - } - - button { - width: 300px; - height: 50px; - font-size: 20px; - } - "# - .into() - } -} - -fn main() { - console_log::init_with_level(Level::Trace).expect("Failed to initialise Log!"); - yew::start_app::(); -}