diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index b0c468c34..050b50283 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -76,7 +76,7 @@ impl VirtualDom { /// Create this template and write its mutations pub(crate) fn create(&mut self, node: &VNode, to: &mut impl WriteMutations) -> usize { - // check for a overriden template + // check for a overridden template #[cfg(debug_assertions)] { let (path, byte_index) = node.template.get().name.rsplit_once(':').unwrap(); @@ -86,14 +86,14 @@ impl VirtualDom { .and_then(|map| map.get(&byte_index.parse().unwrap())) { node.template.set(*template); - } - } - // Initialize the root nodes slice - { - let mut nodes_mut = node.root_ids.borrow_mut(); - let len = node.template.get().roots.len(); - nodes_mut.resize(len, ElementId::default()); + // Initialize the root nodes slice if it was changed + let mut nodes_mut = node.root_ids.borrow_mut(); + let len = node.template.get().roots.len(); + if nodes_mut.len() != len { + *nodes_mut = vec![ElementId::default(); len].into_boxed_slice(); + }; + } }; // The best renderers will have templates prehydrated and registered diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index b9a6bb5c7..b3d65cd9a 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -149,9 +149,9 @@ impl VirtualDom { // Make sure the roots get transferred over while we're here { let mut right = right_template.root_ids.borrow_mut(); - right.clear(); - for &element in left_template.root_ids.borrow().iter() { - right.push(element); + let left = left_template.root_ids.borrow(); + for (from, into) in left.iter().zip(right.iter_mut()) { + *into = *from; } } } diff --git a/packages/core/src/dirty_scope.rs b/packages/core/src/dirty_scope.rs index 87fff3f45..c1380d974 100644 --- a/packages/core/src/dirty_scope.rs +++ b/packages/core/src/dirty_scope.rs @@ -2,12 +2,24 @@ use std::hash::Hash; use crate::ScopeId; -#[derive(Debug, Clone, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Eq)] pub struct DirtyScope { pub height: u32, pub id: ScopeId, } +impl PartialOrd for DirtyScope { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for DirtyScope { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.height.cmp(&other.height).then(self.id.cmp(&other.id)) + } +} + impl PartialEq for DirtyScope { fn eq(&self, other: &Self) -> bool { self.id == other.id diff --git a/packages/core/src/error_boundary.rs b/packages/core/src/error_boundary.rs index c36cd4707..4fe475d33 100644 --- a/packages/core/src/error_boundary.rs +++ b/packages/core/src/error_boundary.rs @@ -287,8 +287,8 @@ fn default_handler(error: CapturedError) -> Element { Some(VNode::new( None, TEMPLATE, - Vec::with_capacity(1usize), - vec![error.to_string().into_dyn_node()], + Box::new([Default::default(); 1]), + Box::new([error.to_string().into_dyn_node()]), Default::default(), )) } @@ -460,8 +460,8 @@ pub fn ErrorBoundary(props: ErrorBoundaryProps) -> Element { VNode::new( None, TEMPLATE, - Vec::with_capacity(1usize), - vec![(props.children).into_dyn_node()], + Box::new([Default::default(); 1]), + Box::new([(props.children).into_dyn_node()]), Default::default(), ) }), diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index 7f4466dd8..41246a196 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -77,8 +77,8 @@ pub use crate::innerlude::{ fc_to_builder, generation, once, schedule_update, schedule_update_any, vdom_is_rendering, AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, Mutation, MutationsVec, Properties, RenderReturn, ScopeId, Task, - Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom, - WriteMutations, + Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder, VText, + VirtualDom, WriteMutations, }; /// The purpose of this module is to alleviate imports of many common types @@ -91,6 +91,7 @@ pub mod prelude { push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever, suspend, use_error_boundary, AnyValue, Component, Element, ErrorBoundary, Event, EventHandler, Fragment, IntoAttributeValue, IntoDynNode, Properties, Runtime, RuntimeGuard, - ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom, + ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VNodeInner, + VirtualDom, }; } diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 0d5d2ae5d..138303eb0 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -4,6 +4,7 @@ use crate::Properties; use crate::{arena::ElementId, Element, Event, ScopeId}; use std::ops::Deref; use std::rc::Rc; +use std::vec; use std::{ any::{Any, TypeId}, cell::{Cell, RefCell}, @@ -53,16 +54,16 @@ pub struct VNodeInner { /// The IDs for the roots of this template - to be used when moving the template around and removing it from /// the actual Dom - pub root_ids: RefCell>, + pub root_ids: RefCell>, /// The static nodes and static descriptor of the template pub template: Cell