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 root_refs: Vec<&Element<'static>> = self.doc.roots.iter().collect();
self.vdom_roots = Interpreter::evaluate_vdom_incr(
&self.doc.roots,
&root_refs,
&mut self.doc.variables,
&self.doc.components,
&self.rhei,

View File

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