From 98ad27fda57f571856f9ca2d334fce59bd0aca20 Mon Sep 17 00:00:00 2001 From: Greg Johnston Date: Wed, 19 Oct 2022 17:09:09 -0400 Subject: [PATCH] Add benchmarks against Yew and Sycamore for server-side rendering --- benchmarks/Cargo.toml | 5 +- benchmarks/src/lib.rs | 161 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 4 deletions(-) diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index eb877f857..15016ae7d 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -5,5 +5,6 @@ edition = "2021" [dev-dependencies] leptos = { path = "../leptos", default-features = false, features = ["ssr"] } -sycamore = "0.8" -yew = "0.19" \ No newline at end of file +sycamore = { version = "0.8", features = ["ssr"] } +yew = { git = "https://github.com/yewstack/yew", features = ["ssr", "tokio"] } +tokio-test = "0.4" \ No newline at end of file diff --git a/benchmarks/src/lib.rs b/benchmarks/src/lib.rs index e0183aee9..cebbdf0e7 100644 --- a/benchmarks/src/lib.rs +++ b/benchmarks/src/lib.rs @@ -1,7 +1,7 @@ #![feature(test)] extern crate test; - +/* mod reactive { use test::Bencher; @@ -162,4 +162,161 @@ mod reactive { } }); } -} +} */ + +mod ssr { + use test::Bencher; + + #[bench] + fn leptos_ssr_bench(b: &mut Bencher) { + use leptos::*; + + b.iter(|| { + _ = create_scope(|cx| { + #[component] + fn Counter(cx: Scope, initial: i32) -> Element { + let (value, set_value) = create_signal(cx, initial); + view! { + cx, +
+ + "Value: " {move || value().to_string()} "!" + +
+ } + } + + let rendered = view! { + cx, +
+

"Welcome to our benchmark page."

+

"Here's some introductory text."

+ + + +
+ }; + + assert_eq!( + rendered, + "

Welcome to our benchmark page.

Here's some introductory text.

Value: 1!
Value: 2!
Value: 3!
" + ); + }); + }); + } + + #[bench] + fn sycamore_ssr_bench(b: &mut Bencher) { + use sycamore::*; + use sycamore::prelude::*; + + b.iter(|| { + _ = create_scope(|cx| { + #[derive(Prop)] + struct CounterProps { + initial: i32 + } + + + #[component] + fn Counter(cx: Scope, props: CounterProps) -> View { + let value = create_signal(cx, props.initial); + view! { + cx, + div { + button(on:click=|_| value.set(*value.get() - 1)) { + "-1" + } + span { + "Value: " + (value.get().to_string()) + "!" + } + button(on:click=|_| value.set(*value.get() + 1)) { + "+1" + } + } + } + } + + let rendered = render_to_string(|cx| view! { + cx, + main { + h1 { + "Welcome to our benchmark page." + } + p { + "Here's some introductory text." + } + Counter(initial = 1) + Counter(initial = 2) + Counter(initial = 3) + } + }); + + assert_eq!( + rendered, + "

Welcome to our benchmark page.

Here's some introductory text.

Value: 1!
Value: 2!
Value: 3!
" + ); + }); + }); + } + + #[bench] + fn yew_ssr_bench(b: &mut Bencher) { + use yew::prelude::*; + use yew::ServerRenderer; + + b.iter(|| { + #[derive(Properties, PartialEq, Eq, Debug)] + struct CounterProps { + initial: i32 + } + + #[function_component(Counter)] + fn counter(props: &CounterProps) -> Html { + let state = use_state(|| props.initial); + + let incr_counter = { + let state = state.clone(); + Callback::from(move |_| state.set(&*state + 1)) + }; + + let decr_counter = { + let state = state.clone(); + Callback::from(move |_| state.set(&*state - 1)) + }; + + html! { +
+

{"Welcome to our benchmark page."}

+

{"Here's some introductory text."}

+ +

{"Value: "} {*state} {"!"}

+ +
+ } + } + + #[function_component] + fn App() -> Html { + html! { +
+ + + +
+ } + } + + tokio_test::block_on(async { + let renderer = ServerRenderer::::new(); + let rendered = renderer.render().await; + assert_eq!( + rendered, + "

Welcome to our benchmark page.

Here's some introductory text.

Value: 1!

Welcome to our benchmark page.

Here's some introductory text.

Value: 2!

Welcome to our benchmark page.

Here's some introductory text.

Value: 3!

" + ); + }); + }); + } +} \ No newline at end of file