You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.
The existing invalidation and rendering system behaves like the following:
Key: Red: Will render Orange: Will potentially render (setProperties will be called) Arrows: Invalidation path Black dot: Source widget that invalidated
As you can see, when Widget J invalidates, we go all the way up the tree to the root invalidating all widgets along the way. We then come back down the tree, definitely re-rendering the branch the invalidated widget was in (in this case Widget A, Widget C, Widget G and Widget J). As well as this, the Widgets marked in orange at least have their setProperties ran on them also. This can be quite/very costly in tree's that have any depth, not only due to the setProperties and render calls, but ultimately the actual dom diffing below.
Proposed system
The proposed system would be a switch to sub tree rendering. This would mean when a widget invalidates only itself is actually guaranteed to be re-rendered, there is no invalidation path up to the top widget and back down the branch, we simply render from the widget that invalidated.
Key: Red: Will render Orange: Will potentially render (setProperties will be called) Black dot: Source widget that invalidated
The above is a good best case scenario compared to the existing system.
In terms of this working as a system we have to take a few extra things into account:
If there are multiple widget invalidations across the tree for one scheduled render, we can now no longer bank on it being picked up in one whole tree render like the existing system did. To deal with this, we need to queue up the widgets that have invalidated, and render those subtrees also.
If there are multiple widget invalidates in the same branch then one is guaranteed to include the other (ie one is higher in the tree, so will render the subtree anyway), if the order means the lower one in the tree is first, then we potentially end up having to render it twice. We can solve this by sorting the render queue by depth, which means the higher up in the tree is guaranteed to be rendered first.
Overall in apps that have any depth of widgets this should offer some serious real world performance benefits, as well as making a more logical pipeline of what happens when a widget is invalidated. This will also enable is in the future to more smartly optimise and schedule rendering on a widget level.
The text was updated successfully, but these errors were encountered:
Since a widget's render() can return DNode | DNode() array, are we sure that the parent will always remain unaffected when the child re-renders (e.g. if a widget changes from a single DNode to a DNode[]?
Also, for completeness we don't express in the diagram what happens to "grandchildren" nodes upon invalidation. For example if Widget G was invalidated, we would have expected Widget L to remain untouched in both scenarios, right?
@kitsonk a parent widget has no knowledge of the outcome of a render from a child widget. To a parent widget it is simply a WNode. In implementation the child widget operates on a parent dom node and thats it.
Yes a grandchild is untouched as long as the parent is not rendered in both scenarios.
Enhancement
Existing system
The existing invalidation and rendering system behaves like the following:
Key:
Red: Will render
Orange: Will potentially render (
setProperties
will be called)Arrows: Invalidation path
Black dot: Source widget that invalidated
As you can see, when
Widget J
invalidates, we go all the way up the tree to the root invalidating all widgets along the way. We then come back down the tree, definitely re-rendering the branch the invalidated widget was in (in this caseWidget A
,Widget C
,Widget G
andWidget J
). As well as this, the Widgets marked in orange at least have theirsetProperties
ran on them also. This can be quite/very costly in tree's that have any depth, not only due to thesetProperties
andrender
calls, but ultimately the actual dom diffing below.Proposed system
The proposed system would be a switch to sub tree rendering. This would mean when a widget invalidates only itself is actually guaranteed to be re-rendered, there is no invalidation path up to the top widget and back down the branch, we simply render from the widget that invalidated.
Key:
Red: Will render
Orange: Will potentially render (
setProperties
will be called)Black dot: Source widget that invalidated
The above is a good best case scenario compared to the existing system.
In terms of this working as a system we have to take a few extra things into account:
If there are multiple widget invalidations across the tree for one scheduled render, we can now no longer bank on it being picked up in one whole tree render like the existing system did. To deal with this, we need to queue up the widgets that have invalidated, and render those subtrees also.
If there are multiple widget invalidates in the same branch then one is guaranteed to include the other (ie one is higher in the tree, so will render the subtree anyway), if the order means the lower one in the tree is first, then we potentially end up having to render it twice. We can solve this by sorting the render queue by depth, which means the higher up in the tree is guaranteed to be rendered first.
Overall in apps that have any depth of widgets this should offer some serious real world performance benefits, as well as making a more logical pipeline of what happens when a widget is invalidated. This will also enable is in the future to more smartly optimise and schedule rendering on a widget level.
The text was updated successfully, but these errors were encountered: