fix: eliminate deep Element cloning in @if by using &[&Element] references
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user