Subtree memorization / reactive templates (#488)
This commit adds subtree memoization to Dioxus. Subtree memoization is basically a compile-time step that drastically reduces the amount of work the diffing engine needs to do at runtime by extracting non-changing nodes out into a static "template." Templates are then understood by the various renderers in the ecosystem as a faster way of rendering the same items. For example, in the web, templates are simply a set of DOM Nodes created once and then cloned later. This is the same pattern frameworks like Lithtml and SolidJS use to achieve near-perfect performance. Subtree memoization adds an additional level of complexity to Dioxus. The RSX macro needs to be much smarter to identify changing/nonchanging nodes and generate a mapping between the Template and its runtime counterparts. This commit represents a working starter point for this work, adding support for templates for the web, desktop, liveview, ssr, and native-core renderers. In the future we will try to shrink code generation, generally improve performance, and simplify our implementation.
This commit is contained in:
1 parent
b32fd2d2cd
commit
047ed1e553
80 files changed
+6774
-2552
No files matched your search
@@ -108,12 +108,30 @@ impl WebsysDom {
|
||||
}
|
||||
|
||||
for listener in vel.listeners {
|
||||
self.interpreter.NewEventListener(
|
||||
listener.event,
|
||||
listener.mounted_node.get().unwrap().as_u64(),
|
||||
self.handler.as_ref().unchecked_ref(),
|
||||
event_bubbles(listener.event),
|
||||
);
|
||||
let global_id = listener.mounted_node.get().unwrap();
|
||||
match global_id {
|
||||
dioxus_core::GlobalNodeId::TemplateId {
|
||||
template_ref_id,
|
||||
template_node_id: id,
|
||||
} => {
|
||||
self.interpreter.EnterTemplateRef(template_ref_id.into());
|
||||
self.interpreter.NewEventListener(
|
||||
listener.event,
|
||||
id.into(),
|
||||
self.handler.as_ref().unchecked_ref(),
|
||||
event_bubbles(listener.event),
|
||||
);
|
||||
self.interpreter.ExitTemplateRef();
|
||||
}
|
||||
dioxus_core::GlobalNodeId::VNodeId(id) => {
|
||||
self.interpreter.NewEventListener(
|
||||
listener.event,
|
||||
id.into(),
|
||||
self.handler.as_ref().unchecked_ref(),
|
||||
event_bubbles(listener.event),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !vel.listeners.is_empty() {
|
||||
@@ -165,6 +183,7 @@ impl WebsysDom {
|
||||
let node = scope.root_node();
|
||||
self.rehydrate_single(nodes, place, dom, node, last_node_was_text)?;
|
||||
}
|
||||
VNode::TemplateRef(_) => todo!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user