Skip to content

Commit

Permalink
Slightly optimise for bundle size.
Browse files Browse the repository at this point in the history
  • Loading branch information
futursolo committed Dec 19, 2022
1 parent 50afc9d commit 71cf2a1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 27 deletions.
56 changes: 34 additions & 22 deletions packages/yew/src/dom_bundle/blist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,34 @@ pub(super) struct BList {
key: Option<Key>,
}

impl BList {
// Unwraps a Vec<VNode> from the children of a VList.
fn unwrap_children(children: Option<Rc<Vec<VNode>>>) -> Vec<VNode> {
children
.map(Rc::try_unwrap)
.unwrap_or_else(|| Ok(Vec::new()))
// Rc::unwrap_or_clone is not stable yet.
.unwrap_or_else(|m| m.to_vec())
impl VList {
/// Splits current VList for BList
fn split_for_bundle(self) -> (Option<Key>, bool, Vec<VNode>) {
let mut fully_keyed = self.fully_keyed();

let mut children = match self.children {
None => Vec::with_capacity(1),
Some(m) => match Rc::try_unwrap(m) {
Ok(m) => m,
Err(e) => {
let mut children = Vec::with_capacity(e.len());
for i in e.as_ref() {
children.push(i.clone());
}
children
}
},
};

if children.is_empty() {
// Without a placeholder the next element becomes first
// and corrupts the order of rendering
// We use empty text element to stake out a place
children.push(VNode::VText(VText::new("")));
fully_keyed = false;
}

(self.key, fully_keyed, children)
}
}

Expand Down Expand Up @@ -433,7 +453,7 @@ impl Reconcilable for VList {
}

fn reconcile(
mut self,
self,
root: &BSubtree,
parent_scope: &AnyScope,
parent: &Element,
Expand All @@ -448,16 +468,8 @@ impl Reconcilable for VList {
// The left items are known since we want to insert them
// (self.children). For the right ones, we will look at the bundle,
// i.e. the current DOM list element that we want to replace with self.
let (key, fully_keyed, lefts) = self.split_for_bundle();

if self.is_empty() {
// Without a placeholder the next element becomes first
// and corrupts the order of rendering
// We use empty text element to stake out a place
self.add_child(VText::new("").into());
}

let fully_keyed = self.fully_keyed();
let lefts = BList::unwrap_children(self.children);
let rights = &mut blist.rev_children;
test_log!("lefts: {:?}", lefts);
test_log!("rights: {:?}", rights);
Expand All @@ -471,7 +483,7 @@ impl Reconcilable for VList {
BList::apply_unkeyed(root, parent_scope, parent, next_sibling, lefts, rights)
};
blist.fully_keyed = fully_keyed;
blist.key = self.key;
blist.key = key;
test_log!("result: {:?}", rights);
first
}
Expand All @@ -491,8 +503,8 @@ mod feat_hydration {
fragment: &mut Fragment,
) -> (NodeRef, Self::Bundle) {
let node_ref = NodeRef::default();
let fully_keyed = self.fully_keyed();
let vchildren = BList::unwrap_children(self.children);

let (key, fully_keyed, vchildren) = self.split_for_bundle();
let mut children = Vec::with_capacity(vchildren.len());

for (index, child) in vchildren.into_iter().enumerate() {
Expand All @@ -512,7 +524,7 @@ mod feat_hydration {
BList {
rev_children: children,
fully_keyed,
key: self.key,
key,
},
)
}
Expand Down
11 changes: 6 additions & 5 deletions packages/yew/src/virtual_dom/vlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub struct VList {
fully_keyed: FullyKeyedState,

pub key: Option<Key>,

/// A padding to reduce bundle size
_padding: u64,
}

impl PartialEq for VList {
Expand Down Expand Up @@ -73,6 +76,7 @@ impl VList {
children: None,
key: None,
fully_keyed: FullyKeyedState::KnownFullyKeyed,
_padding: 0,
}
}

Expand All @@ -82,12 +86,9 @@ impl VList {
fully_keyed: FullyKeyedState::Unknown,
children: Some(Rc::new(children)),
key,
_padding: 0,
};
vlist.fully_keyed = if vlist.fully_keyed() {
FullyKeyedState::KnownFullyKeyed
} else {
FullyKeyedState::KnownMissingKeys
};
vlist.recheck_fully_keyed();
vlist
}

Expand Down

0 comments on commit 71cf2a1

Please sign in to comment.