-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Performance Advice] Patching to single element or custom elements #430
Comments
@sparhami Any notes? |
Within Google we do something similar to keeping a element. If you inspect some google properties like drive or playstore, there are a sprinkling of c-wiz tags that represent patch boundaries. However, the extra tag does carry around some bloat that our users don't like, so our compiler statically drops in something like <form is="hello-world">...</form> and we do a patchouter from there (when we know it is exactly one element). Keep mind that some of our smaller apps just rerender from #app anyway (when the store changes or something) |
@iteriani thanks for reply, but when should i implement the approach of patching to the wrapping custom element, or let's say when i say that the application is getting bigger from being rendered from the root element? For example i'm using IDOM with mentoor.io which sometimes contains like thousands of elements, which can any of it be modified and or added/deleted in any time , when that happens, i patch the root element and the cycle starts from the top again. That's why i posted this topic, from a UX the performance is pretty much perfect in all devices that use the website either mobiles or desktops, but as a matter of improvement i was wondering if i should go with rendering the custom tags inside the dom. |
From a framework perspective, we had to implement patching of single elements so we could embed lifecycle hooks and skipping mechanics. Our users also liked the ability to develop and test components in isolation, which means that every component should be able to repatch itself when their own data changes. If performance seems fine for now, it's probably not a big deal to keep repatching from the top. However, there are devex reasons (and potential perf reasons if you plan on scaling to large eramounts of dom) to having finer grained patches |
@iteriani can you explain a bit more how you patch in a child template using function templateB(el) {
id.patch(el, () => id.text("goodbye"));
}
function templateA(el) {
id.patch(el, () => {
id.elementOpen("div")
id.text("hello")
templateB(id.currentElement());
id.elementClose("div");
});
} Right now, this blows out the text |
The output of our templates emits something like function templateB() {
id.text("goodbye");
}
function templateA() {
id.elementOpen("div")
id.text("hello")
templateB();
id.elementClose("div");
} and we use something like id.patch(el, templateA) |
How does that solve the above problem you were talking about, where the child template might need to patch in new changes based on some bound data changing? |
We have component classes that record their own input parameters as well as internal state. When that changes, we can patch on a subtree. https://github.com/google/closure-templates/blob/master/javascript/element_lib_idom.ts#L62 Similarly, having the templates like above mean that we can take a given element and execute the method at that pointer. |
OK, trying to understand this from scratch so I'm not very educated on the internals of It looks like I appreciate you taking the time to respond to my newbie questions! |
You can take a look here when we expect a SoyElement to be created on a root element, we call this to look for an element with the expected key. If it does not exist, create one and continue the patch from the soy element. |
@iteriani Consider the following: // main function
function page() {
id.elementOpen('div', null, null, 'id', 'main-div');
id.elementOpen('span');
id.text('Spanner');
id.elementClose('span');
callComponentA();
id.elementOpen('span');
id.text('Another Spanner');
id.elementClose('span');
id.elementClose('div');
}
// ComponentA
class ComponentA {
constructor() {
this.nameIsChanged = false;
// for sake of example
setTimeout(() => {
this.nameIsChanged = true;
// re render again in somehow...
}, 5000);
}
render() {
id.elementOpen('div');
id.text('Hello');
if (this.nameIsChanged) {
id.text('You Changed Your Name!');
}
id.elementClose('div');
}
}
// patch the page
id.patch(document.getElementById('app'), page); Here in that example above, can we perform patch over the In other words, how would we update the position of the Also adding a wrapper tag for each component, won't that affect the overall performance by adding new unnecessary nodes to the DOM? Aren't there a similar way to React Fragment that wraps up all its element into a some mystery holder? Sorry for the too many questions but this is really driving me crazy. |
Sorry just got back to this! The way we do this should be documented in these files https://github.com/google/closure-templates/blob/master/javascript/element_lib_idom.ts one example output of "callComponentA" is in this snippet
|
I read these files but it doesn't illustrate how that would happen in the given case above. Also the snippet is not so clear to get the point from it. Can you please provide a snippet code using IDOM without Soy to be more clear to me. Also an idea came into mind that when the inner component has change i will trigger update from its parent component/element which will re-render the entire parent component "the component to be updated plus any other sibling component/element (s)". Would that be a proper approach to go with? |
@iteriani thank you for sharing that code snippet, that's actually very helpful for use cases that do include soy. how is this code generated? is it coming from the soy compiler, or somewhere else? just wondering because we are also looking into how we might componentize. |
This is part of the Soy compiler itself. Instead of writing {template}, you write {element}. So something like {element .foo} |
@iteriani wtf that's amazing |
Hello,
I'm using IDOM to manipulate my HTML DOM which works perfectly fine.
Here is a code snippet to illustrate my point
The main page The static one
Now when the user hits the
/home
page, the#app
gets the following component content:home-page.component.html
hello-world.component.html
I'm using
Two-way data binding
which is applied in theusername
input as when thethis.username
property is changed, the input value is changed as well and vice versa.When any change happens to any property i.e
this.username
i re-run the patcher from thehome-page.component.html
as it will go through all elements from the top.the
<hello-world>
component is removed and its content is added instead.For example the actual output in the browser will be something like:
Now my question: As i mentioned earlier, i'm applying the
patch
function to my#app
tag which contains the content of thehome-page.component.html
file.Should i leave the
hello-world
tag in the dom and apply thepatch
function to that element? i.e the dom will look like:Or leaving the patch function to the
#app
element.The text was updated successfully, but these errors were encountered: