Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

Sub tree rendering #767

Closed
matt-gadd opened this issue Nov 13, 2017 · 2 comments
Closed

Sub tree rendering #767

matt-gadd opened this issue Nov 13, 2017 · 2 comments
Assignees
Milestone

Comments

@matt-gadd
Copy link
Contributor

matt-gadd commented Nov 13, 2017

Enhancement

Existing system

The existing invalidation and rendering system behaves like the following:

image

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.

image

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.

@matt-gadd matt-gadd changed the title SubTree rendering Sub tree rendering Nov 13, 2017
@kitsonk
Copy link
Member

kitsonk commented Nov 13, 2017

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?

@matt-gadd
Copy link
Contributor Author

matt-gadd commented Nov 13, 2017

@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.

@kitsonk kitsonk modified the milestones: 2017.12, beta.5 Nov 29, 2017
@kitsonk kitsonk added rc and removed beta5 labels Nov 30, 2017
@kitsonk kitsonk modified the milestones: beta.5, rc.1 Dec 11, 2017
@kitsonk kitsonk modified the milestones: rc.1, beta.5 Dec 14, 2017
@agubler agubler removed this from the beta.5 milestone Jan 4, 2018
@agubler agubler added this to the rc.1 milestone Jan 22, 2018
@agubler agubler added rc and removed discussion labels Jan 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants