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:
Demonthos authored and GitHub committed 2022-09-30 12:03:06 -07:00
1 parent b32fd2d2cd
commit 047ed1e553
80 files changed
+6774 -2552

No files matched your search

+30 -20
View File
@@ -1,5 +1,4 @@
use dioxus_core::*;
use std::fmt::Arguments;
macro_rules! no_namespace_trait_methods {
(
@@ -9,10 +8,12 @@ macro_rules! no_namespace_trait_methods {
)*
) => {
$(
$(#[$attr])*
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
cx.attr(stringify!($name), val, None, false)
}
#[allow(non_upper_case_globals)]
const $name: AttributeDiscription = AttributeDiscription{
name: stringify!($name),
namespace: None,
volatile: false
};
)*
};
}
@@ -24,11 +25,12 @@ macro_rules! style_trait_methods {
)*
) => {
$(
#[inline]
$(#[$attr])*
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
cx.attr($lit, val, Some("style"), false)
}
#[allow(non_upper_case_globals)]
const $name: AttributeDiscription = AttributeDiscription{
name: $lit,
namespace: Some("style"),
volatile: false
};
)*
};
}
@@ -40,10 +42,12 @@ macro_rules! aria_trait_methods {
)*
) => {
$(
$(#[$attr])*
fn $name<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
cx.attr($lit, val, None, false)
}
#[allow(non_upper_case_globals)]
const $name: AttributeDiscription = AttributeDiscription{
name: $lit,
namespace: None,
volatile: false
};
)*
};
}
@@ -53,9 +57,12 @@ pub trait GlobalAttributes {
///
/// For more information, see the MDN docs:
/// <https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault>
fn prevent_default<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
cx.attr("dioxus-prevent-default", val, None, false)
}
#[allow(non_upper_case_globals)]
const prevent_default: AttributeDiscription = AttributeDiscription {
name: "dioxus-prevent-default",
namespace: None,
volatile: false,
};
no_namespace_trait_methods! {
accesskey;
@@ -597,9 +604,12 @@ pub trait SvgAttributes {
///
/// For more information, see the MDN docs:
/// <https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault>
fn prevent_default<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
cx.attr("dioxus-prevent-default", val, None, false)
}
#[allow(non_upper_case_globals)]
const prevent_default: AttributeDiscription = AttributeDiscription {
name: "dioxus-prevent-default",
namespace: None,
volatile: false,
};
aria_trait_methods! {
accent_height: "accent-height",
accumulate: "accumulate",