Add benchmarks against Yew and Sycamore for server-side rendering

This commit is contained in:
Greg Johnston 2022-10-19 17:09:09 -04:00
parent db3a9c98e7
commit 98ad27fda5
2 changed files with 162 additions and 4 deletions

View file

@ -5,5 +5,6 @@ edition = "2021"
[dev-dependencies]
leptos = { path = "../leptos", default-features = false, features = ["ssr"] }
sycamore = "0.8"
yew = "0.19"
sycamore = { version = "0.8", features = ["ssr"] }
yew = { git = "https://github.com/yewstack/yew", features = ["ssr", "tokio"] }
tokio-test = "0.4"

View file

@ -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,
<div>
<button on:click=move |_| set_value.update(|value| *value -= 1)>"-1"</button>
<span>"Value: " {move || value().to_string()} "!"</span>
<button on:click=move |_| set_value.update(|value| *value += 1)>"+1"</button>
</div>
}
}
let rendered = view! {
cx,
<main>
<h1>"Welcome to our benchmark page."</h1>
<p>"Here's some introductory text."</p>
<Counter initial=1/>
<Counter initial=2/>
<Counter initial=3/>
</main>
};
assert_eq!(
rendered,
"<main data-hk=\"0-0\"><h1>Welcome to our benchmark page.</h1><p>Here's some introductory text.</p><!--#--><div data-hk=\"0-2-0\"><button>-1</button><span>Value: <!--#-->1<!--/-->!</span><button>+1</button></div><!--/--><!--#--><div data-hk=\"0-3-0\"><button>-1</button><span>Value: <!--#-->2<!--/-->!</span><button>+1</button></div><!--/--><!--#--><div data-hk=\"0-4-0\"><button>-1</button><span>Value: <!--#-->3<!--/-->!</span><button>+1</button></div><!--/--></main>"
);
});
});
}
#[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<G: Html>(cx: Scope, props: CounterProps) -> View<G> {
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,
"<main data-hk=\"0.0\"><h1 data-hk=\"0.1\">Welcome to our benchmark page.</h1><p data-hk=\"0.2\">Here's some introductory text.</p><!--#--><div data-hk=\"1.0\"><button data-hk=\"1.1\">-1</button><span data-hk=\"1.2\">Value: <!--#-->1<!--/-->!</span><button data-hk=\"1.3\">+1</button></div><!--/--><!----><!--#--><div data-hk=\"2.0\"><button data-hk=\"2.1\">-1</button><span data-hk=\"2.2\">Value: <!--#-->2<!--/-->!</span><button data-hk=\"2.3\">+1</button></div><!--/--><!----><!--#--><div data-hk=\"3.0\"><button data-hk=\"3.1\">-1</button><span data-hk=\"3.2\">Value: <!--#-->3<!--/-->!</span><button data-hk=\"3.3\">+1</button></div><!--/--></main>"
);
});
});
}
#[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! {
<div>
<h1>{"Welcome to our benchmark page."}</h1>
<p>{"Here's some introductory text."}</p>
<button onclick={decr_counter}> {"-1"} </button>
<p> {"Value: "} {*state} {"!"} </p>
<button onclick={incr_counter}> {"+1"} </button>
</div>
}
}
#[function_component]
fn App() -> Html {
html! {
<main>
<Counter initial=1/>
<Counter initial=2/>
<Counter initial=3/>
</main>
}
}
tokio_test::block_on(async {
let renderer = ServerRenderer::<App>::new();
let rendered = renderer.render().await;
assert_eq!(
rendered,
"<!--<[]>--><main><!--<[]>--><div><h1>Welcome to our benchmark page.</h1><p>Here's some introductory text.</p><button>-1</button><p>Value: 1!</p><button>+1</button></div><!--</[]>--><!--<[]>--><div><h1>Welcome to our benchmark page.</h1><p>Here's some introductory text.</p><button>-1</button><p>Value: 2!</p><button>+1</button></div><!--</[]>--><!--<[]>--><div><h1>Welcome to our benchmark page.</h1><p>Here's some introductory text.</p><button>-1</button><p>Value: 3!</p><button>+1</button></div><!--</[]>--></main><!--</[]>-->"
);
});
});
}
}