diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index b0a463c9e..c5e2c6b1c 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -35,6 +35,9 @@ impl<'b> VirtualDom { let cur_scope = self.scope_stack.last().copied().unwrap(); + // we know that this will generate at least one mutation per node + self.mutations.edits.reserve(template.template.roots.len()); + let mut on_stack = 0; for (root_idx, root) in template.template.roots.iter().enumerate() { // We might need to generate an ID for the root node @@ -207,19 +210,12 @@ impl<'b> VirtualDom { // If it's all dynamic nodes, then we don't need to register it // Quickly run through and see if it's all just dynamic nodes - let dynamic_roots = template - .template - .roots - .iter() - .filter(|root| { - matches!( - root, - TemplateNode::Dynamic(_) | TemplateNode::DynamicText(_) - ) - }) - .count(); - - if dynamic_roots == template.template.roots.len() { + if template.template.roots.iter().all(|root| { + matches!( + root, + TemplateNode::Dynamic(_) | TemplateNode::DynamicText(_) + ) + }) { return; } @@ -290,7 +286,7 @@ impl<'b> VirtualDom { } pub(crate) fn create_fragment(&mut self, nodes: &'b [VNode<'b>]) -> usize { - nodes.iter().fold(0, |acc, child| acc + self.create(child)) + nodes.iter().map(|child| self.create(child)).sum() } pub(super) fn create_component_node( @@ -301,7 +297,7 @@ impl<'b> VirtualDom { ) -> usize { let props = component .props - .replace(None) + .take() .expect("Props to always exist when a component is being created"); let unbounded_props = unsafe { std::mem::transmute(props) }; diff --git a/packages/core/src/mutations.rs b/packages/core/src/mutations.rs index 2343c4548..3687cd956 100644 --- a/packages/core/src/mutations.rs +++ b/packages/core/src/mutations.rs @@ -1,6 +1,6 @@ use fxhash::FxHashSet; -use crate::{arena::ElementId, ScopeId, ScopeState, Template}; +use crate::{arena::ElementId, ScopeId, Template}; /// A container for all the relevant steps to modify the Real DOM /// @@ -257,9 +257,3 @@ pub enum Mutation<'a> { id: ElementId, }, } - -#[test] -fn sizes() { - println!("mutations: {}", std::mem::size_of::()); - println!("scope: {}", std::mem::size_of::()); -} diff --git a/packages/core/src/scope_arena.rs b/packages/core/src/scope_arena.rs index b4cc54c19..d9e13baea 100644 --- a/packages/core/src/scope_arena.rs +++ b/packages/core/src/scope_arena.rs @@ -9,6 +9,7 @@ use crate::{ virtual_dom::VirtualDom, AttributeValue, DynamicNode, VNode, }; +use bumpalo::Bump; use futures_util::FutureExt; use std::{ mem, @@ -94,7 +95,13 @@ impl VirtualDom { let mut new_nodes = unsafe { let scope = self.scopes[scope_id.0].as_mut(); - scope.previous_frame_mut().bump.reset(); + // if this frame hasn't been intialized yet, we can guess the size of the next frame to be more efficient + if scope.previous_frame().bump.allocated_bytes() == 0 { + scope.previous_frame_mut().bump = + Bump::with_capacity(scope.current_frame().bump.allocated_bytes()); + } else { + scope.previous_frame_mut().bump.reset(); + } // Make sure to reset the hook counter so we give out hooks in the right order scope.hook_idx.set(0); @@ -160,8 +167,8 @@ impl VirtualDom { let frame = scope.previous_frame(); // set the new head of the bump frame - let alloced = &*frame.bump.alloc(new_nodes); - frame.node.set(alloced); + let allocated = &*frame.bump.alloc(new_nodes); + frame.node.set(allocated); // And move the render generation forward by one scope.render_cnt.set(scope.render_cnt.get() + 1); @@ -173,6 +180,6 @@ impl VirtualDom { }); // rebind the lifetime now that its stored internally - unsafe { mem::transmute(alloced) } + unsafe { mem::transmute(allocated) } } }