incremental.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #![allow(unused)]
  2. use std::time::Duration;
  3. use dioxus::prelude::*;
  4. use dioxus_router::prelude::*;
  5. use criterion::{black_box, criterion_group, criterion_main, Criterion};
  6. use dioxus_ssr::Renderer;
  7. pub fn criterion_benchmark(c: &mut Criterion) {
  8. c.bench_function("build 1000 routes", |b| {
  9. let mut renderer = IncrementalRenderer::builder(DefaultRenderer {
  10. before_body: r#"<!DOCTYPE html>
  11. <html lang="en">
  12. <head>
  13. <meta charset="UTF-8">
  14. <meta name="viewport" content="width=device-width,
  15. initial-scale=1.0">
  16. <title>Dioxus Application</title>
  17. </head>
  18. <body>"#
  19. .to_string(),
  20. after_body: r#"</body>
  21. </html>"#
  22. .to_string(),
  23. })
  24. .static_dir("./static")
  25. .invalidate_after(Duration::from_secs(10))
  26. .build();
  27. b.iter(|| {
  28. tokio::runtime::Runtime::new().unwrap().block_on(async {
  29. for id in 0..1000 {
  30. render_route(
  31. &mut renderer,
  32. Route::Post { id },
  33. &mut tokio::io::sink(),
  34. |_| {},
  35. )
  36. .await
  37. .unwrap();
  38. }
  39. })
  40. })
  41. });
  42. c.bench_function("build 1000 routes no memory cache", |b| {
  43. b.to_async(tokio::runtime::Runtime::new().unwrap())
  44. .iter(|| async {
  45. let mut renderer = IncrementalRenderer::builder(DefaultRenderer {
  46. before_body: r#"<!DOCTYPE html>
  47. <html lang="en">
  48. <head>
  49. <meta charset="UTF-8">
  50. <meta name="viewport" content="width=device-width,
  51. initial-scale=1.0">
  52. <title>Dioxus Application</title>
  53. </head>
  54. <body>"#
  55. .to_string(),
  56. after_body: r#"</body>
  57. </html>"#
  58. .to_string(),
  59. })
  60. .static_dir("./static")
  61. .memory_cache_limit(0)
  62. .invalidate_after(Duration::from_secs(10))
  63. .build();
  64. for id in 0..1000 {
  65. render_route(
  66. &mut renderer,
  67. Route::Post { id },
  68. &mut tokio::io::sink(),
  69. |_| {},
  70. )
  71. .await
  72. .unwrap();
  73. }
  74. })
  75. });
  76. c.bench_function("build 1000 routes no cache", |b| {
  77. let mut renderer = Renderer::default();
  78. b.iter(|| {
  79. for id in 0..1000 {
  80. let mut vdom = VirtualDom::new_with_props(
  81. RenderPath,
  82. RenderPathProps::builder().path(Route::Post { id }).build(),
  83. );
  84. vdom.rebuild();
  85. struct Ignore;
  86. impl std::fmt::Write for Ignore {
  87. fn write_str(&mut self, s: &str) -> std::fmt::Result {
  88. Ok(())
  89. }
  90. }
  91. renderer.render_to(&mut Ignore, &vdom).unwrap();
  92. }
  93. })
  94. });
  95. c.bench_function("cache static", |b| {
  96. b.to_async(tokio::runtime::Runtime::new().unwrap())
  97. .iter(|| async {
  98. let mut renderer = IncrementalRenderer::builder(DefaultRenderer {
  99. before_body: r#"<!DOCTYPE html>
  100. <html lang="en">
  101. <head>
  102. <meta charset="UTF-8">
  103. <meta name="viewport" content="width=device-width,
  104. initial-scale=1.0">
  105. <title>Dioxus Application</title>
  106. </head>
  107. <body>"#
  108. .to_string(),
  109. after_body: r#"</body>
  110. </html>"#
  111. .to_string(),
  112. })
  113. .static_dir("./static")
  114. .build();
  115. pre_cache_static_routes::<Route, _>(&mut renderer)
  116. .await
  117. .unwrap();
  118. })
  119. });
  120. }
  121. criterion_group!(benches, criterion_benchmark);
  122. criterion_main!(benches);
  123. #[component]
  124. fn Blog() -> Element {
  125. rsx! {
  126. div {
  127. "Blog"
  128. }
  129. }
  130. }
  131. #[component]
  132. fn Post(id: usize) -> Element {
  133. rsx! {
  134. for _ in 0..*id {
  135. div {
  136. "PostId: {id}"
  137. }
  138. }
  139. }
  140. }
  141. #[component]
  142. fn PostHome() -> Element {
  143. rsx! {
  144. div {
  145. "Post"
  146. }
  147. }
  148. }
  149. #[component]
  150. fn Home() -> Element {
  151. rsx! {
  152. div {
  153. "Home"
  154. }
  155. }
  156. }
  157. #[rustfmt::skip]
  158. #[derive(Clone, Debug, PartialEq, Routable)]
  159. enum Route {
  160. #[nest("/blog")]
  161. #[route("/")]
  162. Blog {},
  163. #[route("/post/index")]
  164. PostHome {},
  165. #[route("/post/:id")]
  166. Post {
  167. id: usize,
  168. },
  169. #[end_nest]
  170. #[route("/")]
  171. Home {},
  172. }
  173. #[component]
  174. fn RenderPath(path: Route) -> Element {
  175. let path = path.clone();
  176. rsx! {
  177. Router::<Route> {
  178. config: || RouterConfig::default().history(MemoryHistory::with_initial_path(path))
  179. }
  180. }
  181. }