fix: eliminate deep Element cloning in @if by using &[&Element] references

This commit is contained in:
Glint Dev
2026-07-22 13:35:12 +03:00
parent fd2863678b
commit be6d5c36fc
2 changed files with 16 additions and 10 deletions

View File

@@ -55,8 +55,9 @@ impl GlintApp {
} }
let dirty_set = self.doc.tracker.take_dirty_set(); let dirty_set = self.doc.tracker.take_dirty_set();
let root_refs: Vec<&Element<'static>> = self.doc.roots.iter().collect();
self.vdom_roots = Interpreter::evaluate_vdom_incr( self.vdom_roots = Interpreter::evaluate_vdom_incr(
&self.doc.roots, &root_refs,
&mut self.doc.variables, &mut self.doc.variables,
&self.doc.components, &self.doc.components,
&self.rhei, &self.rhei,

View File

@@ -329,11 +329,12 @@ impl Interpreter {
stylesheet: &SS, stylesheet: &SS,
ancestors: &[AncestorInfo], ancestors: &[AncestorInfo],
) -> Vec<Element<'a>> { ) -> Vec<Element<'a>> {
Self::evaluate_vdom_incr(templates, variables, components, rhei, stylesheet, ancestors, &HashSet::new()) let refs: Vec<&Element<'a>> = templates.iter().collect();
Self::evaluate_vdom_incr(&refs, variables, components, rhei, stylesheet, ancestors, &HashSet::new())
} }
pub fn evaluate_vdom_incr<'a>( pub fn evaluate_vdom_incr<'a>(
templates: &[Element<'a>], templates: &[&Element<'a>],
variables: &mut HashMap<String, Value>, variables: &mut HashMap<String, Value>,
components: &HashMap<String, ComponentDef<'a>>, components: &HashMap<String, ComponentDef<'a>>,
rhei: &RheiContext, rhei: &RheiContext,
@@ -382,12 +383,12 @@ impl Interpreter {
let cond = el.get_prop("condition").unwrap_or_default(); let cond = el.get_prop("condition").unwrap_or_default();
let is_true = Self::evaluate_condition(cond, variables, rhei); let is_true = Self::evaluate_condition(cond, variables, rhei);
let mut active_branch = Vec::new(); let mut active_branch: Vec<&Element<'a>> = Vec::new();
for child in &el.children { for child in el.children.iter() {
if child.type_name == "@else" { if child.type_name == "@else" {
if !is_true { active_branch.extend(child.children.clone()); } if !is_true { active_branch.extend(child.children.iter()); }
} else if is_true { } else if is_true {
active_branch.push(child.clone()); active_branch.push(child);
} }
} }
output.extend(Self::evaluate_vdom_incr( output.extend(Self::evaluate_vdom_incr(
@@ -411,11 +412,13 @@ impl Interpreter {
resolved_source.split(',').map(str::trim).map(str::to_string).collect() resolved_source.split(',').map(str::trim).map(str::to_string).collect()
}; };
let child_refs: Vec<&Element<'a>> = el.children.iter().collect();
for item in items { for item in items {
let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item))); let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item)));
output.extend(Self::evaluate_vdom_incr( output.extend(Self::evaluate_vdom_incr(
&el.children, variables, components, rhei, stylesheet, ancestors, dirty_set, &child_refs, variables, components, rhei, stylesheet, ancestors, dirty_set,
)); ));
if let Some(old) = old_val { if let Some(old) = old_val {
@@ -456,8 +459,9 @@ impl Interpreter {
vcomp.computed_style = ComputedStyle::compute(&vcomp.properties, &matched_sheets); vcomp.computed_style = ComputedStyle::compute(&vcomp.properties, &matched_sheets);
let child_ancestors = Self::build_ancestor_chain(ancestors, &vcomp); let child_ancestors = Self::build_ancestor_chain(ancestors, &vcomp);
let comp_child_refs: Vec<&Element<'a>> = comp.children.iter().collect();
vcomp.children = Self::evaluate_vdom_incr( vcomp.children = Self::evaluate_vdom_incr(
&comp.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set, &comp_child_refs, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
); );
output.push(vcomp); output.push(vcomp);
@@ -488,8 +492,9 @@ impl Interpreter {
vnode.computed_style = ComputedStyle::compute(&vnode.properties, &matched_sheets); vnode.computed_style = ComputedStyle::compute(&vnode.properties, &matched_sheets);
let child_ancestors = Self::build_ancestor_chain(ancestors, &vnode); let child_ancestors = Self::build_ancestor_chain(ancestors, &vnode);
let child_refs: Vec<&Element<'a>> = el.children.iter().collect();
vnode.children = Self::evaluate_vdom_incr( vnode.children = Self::evaluate_vdom_incr(
&el.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set, &child_refs, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
); );
output.push(vnode); output.push(vnode);
} }