From 38a1fedd86057224b7dc7167abdbb5faf5a44a18 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Tue, 2 Aug 2022 23:29:36 +0900 Subject: [PATCH 1/9] Fix rendering stream. --- packages/yew/src/virtual_dom/vlist.rs | 53 ++++++++++++++++++--------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 5b9c64b93f0..d3fb6159c5e 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -156,7 +156,8 @@ mod test { #[cfg(feature = "ssr")] mod feat_ssr { - use futures::stream::{FuturesOrdered, StreamExt}; + use futures::future; + use futures::stream::{FuturesUnordered, StreamExt}; use super::*; use crate::html::AnyScope; @@ -176,26 +177,42 @@ mod feat_ssr { } _ => { let buf_capacity = w.capacity(); + let mut children_streams = Vec::with_capacity(self.children.len()); + let mut children_furs = FuturesUnordered::new(); + + let mut children = self.children.iter(); + let first_child = children.next().expect("first child should exist!"); // Concurrently render all children. - let mut children: FuturesOrdered<_> = self - .children - .iter() - .map(|m| async move { - let (mut w, r) = io::buffer(buf_capacity); - - m.render_into_stream(&mut w, parent_scope, hydratable).await; - drop(w); - - r - }) - .collect(); - - while let Some(mut r) = children.next().await { - while let Some(next_chunk) = r.next().await { - w.write(next_chunk.into()); - } + for child in children { + let (mut w, r) = io::buffer(buf_capacity); + + children_furs.push(async move { + child + .render_into_stream(&mut w, parent_scope, hydratable) + .await; + }); + + children_streams.push(r); } + + // Concurrently resolve all futures. + let resolve_fur = async move { while children_furs.next().await.is_some() {} }; + + // Transfer results to parent writer. + let transfer_fur = async move { + first_child + .render_into_stream(w, parent_scope, hydratable) + .await; + + for mut r in children_streams.into_iter() { + while let Some(next_chunk) = r.next().await { + w.write(next_chunk.into()); + } + } + }; + + future::join(resolve_fur, transfer_fur).await; } } } From 2038c775f8828a9ec71b754e9c414caa15f08add Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Tue, 2 Aug 2022 23:39:03 +0900 Subject: [PATCH 2/9] Update naming. --- packages/yew/src/virtual_dom/vlist.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index d3fb6159c5e..9ddd69c15ed 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -177,8 +177,8 @@ mod feat_ssr { } _ => { let buf_capacity = w.capacity(); - let mut children_streams = Vec::with_capacity(self.children.len()); - let mut children_furs = FuturesUnordered::new(); + let mut child_streams = Vec::with_capacity(self.children.len()); + let mut child_furs = FuturesUnordered::new(); let mut children = self.children.iter(); let first_child = children.next().expect("first child should exist!"); @@ -187,17 +187,17 @@ mod feat_ssr { for child in children { let (mut w, r) = io::buffer(buf_capacity); - children_furs.push(async move { + child_furs.push(async move { child .render_into_stream(&mut w, parent_scope, hydratable) .await; }); - children_streams.push(r); + child_streams.push(r); } // Concurrently resolve all futures. - let resolve_fur = async move { while children_furs.next().await.is_some() {} }; + let resolve_fur = async move { while child_furs.next().await.is_some() {} }; // Transfer results to parent writer. let transfer_fur = async move { @@ -205,14 +205,14 @@ mod feat_ssr { .render_into_stream(w, parent_scope, hydratable) .await; - for mut r in children_streams.into_iter() { + for mut r in child_streams { while let Some(next_chunk) = r.next().await { w.write(next_chunk.into()); } } }; - future::join(resolve_fur, transfer_fur).await; + future::join(transfer_fur, resolve_fur).await; } } } From 9a5f2b2f7817af4df50cd17000b2c45c817a93c6 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Wed, 3 Aug 2022 02:09:48 +0900 Subject: [PATCH 3/9] Resolve first, then transfer. --- packages/yew/src/virtual_dom/vlist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 9ddd69c15ed..0b0ef54ad69 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -177,7 +177,7 @@ mod feat_ssr { } _ => { let buf_capacity = w.capacity(); - let mut child_streams = Vec::with_capacity(self.children.len()); + let mut child_streams = Vec::with_capacity(self.children.len() - 1); let mut child_furs = FuturesUnordered::new(); let mut children = self.children.iter(); @@ -212,7 +212,7 @@ mod feat_ssr { } }; - future::join(transfer_fur, resolve_fur).await; + future::join(resolve_fur, transfer_fur).await; } } } From 1511f8892e289fe6088805af5f4978ac3a1c8c50 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Wed, 3 Aug 2022 02:59:47 +0900 Subject: [PATCH 4/9] Use slice pattern. --- packages/yew/src/virtual_dom/vlist.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 0b0ef54ad69..3f48fd90beb 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -175,16 +175,13 @@ mod feat_ssr { [child] => { child.render_into_stream(w, parent_scope, hydratable).await; } - _ => { + [first_child, rest_children @ ..] => { let buf_capacity = w.capacity(); let mut child_streams = Vec::with_capacity(self.children.len() - 1); let mut child_furs = FuturesUnordered::new(); - let mut children = self.children.iter(); - let first_child = children.next().expect("first child should exist!"); - - // Concurrently render all children. - for child in children { + // Concurrently render rest children into a separate buffer. + for child in rest_children { let (mut w, r) = io::buffer(buf_capacity); child_furs.push(async move { @@ -196,11 +193,12 @@ mod feat_ssr { child_streams.push(r); } - // Concurrently resolve all futures. + // Concurrently resolve all child futures. let resolve_fur = async move { while child_furs.next().await.is_some() {} }; // Transfer results to parent writer. let transfer_fur = async move { + // Render first child to parent buffer directly. first_child .render_into_stream(w, parent_scope, hydratable) .await; From bbe03943b0bf36db5373a43f0cdccdcae1edd28b Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Wed, 3 Aug 2022 20:37:11 +0900 Subject: [PATCH 5/9] Update workflow paths. --- .github/workflows/benchmark-ssr.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/benchmark-ssr.yml b/.github/workflows/benchmark-ssr.yml index 7db9d3052a6..ca4d082b049 100644 --- a/.github/workflows/benchmark-ssr.yml +++ b/.github/workflows/benchmark-ssr.yml @@ -6,9 +6,10 @@ on: branches: [master] paths: - .github/workflows/benchmark-ssr.yml - - "packages/yew" - - "examples/function_router" - - "tools/benchmark-ssr" + - "packages/yew/**" + - "packages/yew-router/**" + - "examples/function_router/**" + - "tools/benchmark-ssr/**" jobs: benchmark-ssr: From 87d7926fc49c6538f6c264a82a2a1d1323dece3e Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Sun, 7 Aug 2022 00:42:09 +0900 Subject: [PATCH 6/9] Use join_all. --- packages/yew/src/virtual_dom/vlist.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 3f48fd90beb..23c1e7b126a 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -156,8 +156,8 @@ mod test { #[cfg(feature = "ssr")] mod feat_ssr { - use futures::future; use futures::stream::{FuturesUnordered, StreamExt}; + use futures::{future, FutureExt}; use super::*; use crate::html::AnyScope; @@ -178,31 +178,37 @@ mod feat_ssr { [first_child, rest_children @ ..] => { let buf_capacity = w.capacity(); let mut child_streams = Vec::with_capacity(self.children.len() - 1); - let mut child_furs = FuturesUnordered::new(); // Concurrently render rest children into a separate buffer. - for child in rest_children { + let rest_child_furs = rest_children.iter().map(|child| { let (mut w, r) = io::buffer(buf_capacity); - child_furs.push(async move { + child_streams.push(r); + + async move { child .render_into_stream(&mut w, parent_scope, hydratable) .await; - }); - - child_streams.push(r); - } + } + }); // Concurrently resolve all child futures. - let resolve_fur = async move { while child_furs.next().await.is_some() {} }; + let resolve_fur = if rest_children.len() <= 30 { + // 30 is selected by join_all to be deemed small. + future::join_all(rest_child_furs).map(|_| {}).left_future() + } else { + let mut rest_child_furs: FuturesUnordered<_> = rest_child_furs.collect(); + async move { while rest_child_furs.next().await.is_some() {} } + .right_future() + }; - // Transfer results to parent writer. let transfer_fur = async move { // Render first child to parent buffer directly. first_child .render_into_stream(w, parent_scope, hydratable) .await; + // Transfer results to parent writer. for mut r in child_streams { while let Some(next_chunk) = r.next().await { w.write(next_chunk.into()); From 4116d2bd69a1f1d977d67460ebfb52e1857ee6d7 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Sun, 7 Aug 2022 00:45:45 +0900 Subject: [PATCH 7/9] Do not map. --- packages/yew/src/virtual_dom/vlist.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 23c1e7b126a..8c44651f1ac 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -195,7 +195,8 @@ mod feat_ssr { // Concurrently resolve all child futures. let resolve_fur = if rest_children.len() <= 30 { // 30 is selected by join_all to be deemed small. - future::join_all(rest_child_furs).map(|_| {}).left_future() + let rest_child_furs = future::join_all(rest_child_furs); + async move { rest_child_furs.map(|_| {}).await }.left_future() } else { let mut rest_child_furs: FuturesUnordered<_> = rest_child_furs.collect(); async move { while rest_child_furs.next().await.is_some() {} } From d74d9f905233eb1c3a47c325a4daae598ae73012 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Sun, 7 Aug 2022 00:52:48 +0900 Subject: [PATCH 8/9] Remove map. --- packages/yew/src/virtual_dom/vlist.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index 8c44651f1ac..a5c5d4b7459 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -196,7 +196,7 @@ mod feat_ssr { let resolve_fur = if rest_children.len() <= 30 { // 30 is selected by join_all to be deemed small. let rest_child_furs = future::join_all(rest_child_furs); - async move { rest_child_furs.map(|_| {}).await }.left_future() + async move { rest_child_furs.await; }.left_future() } else { let mut rest_child_furs: FuturesUnordered<_> = rest_child_furs.collect(); async move { while rest_child_furs.next().await.is_some() {} } From d0ed690b40eab0d7c9a5027a3b827c2b1b3b7896 Mon Sep 17 00:00:00 2001 From: Kaede Hoshikawa Date: Sun, 7 Aug 2022 00:55:01 +0900 Subject: [PATCH 9/9] Fix rustfmt. --- packages/yew/src/virtual_dom/vlist.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/yew/src/virtual_dom/vlist.rs b/packages/yew/src/virtual_dom/vlist.rs index a5c5d4b7459..f139c2e179f 100644 --- a/packages/yew/src/virtual_dom/vlist.rs +++ b/packages/yew/src/virtual_dom/vlist.rs @@ -196,7 +196,10 @@ mod feat_ssr { let resolve_fur = if rest_children.len() <= 30 { // 30 is selected by join_all to be deemed small. let rest_child_furs = future::join_all(rest_child_furs); - async move { rest_child_furs.await; }.left_future() + async move { + rest_child_furs.await; + } + .left_future() } else { let mut rest_child_furs: FuturesUnordered<_> = rest_child_furs.collect(); async move { while rest_child_furs.next().await.is_some() {} }