incremental.rs 4.8 KB

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