[Fiber] Host Side Effects#7154
Conversation
7a0fad0 to
6fb5034
Compare
| // us to reuse a slice of the linked list when we reuse the work done within | ||
| // this fiber. | ||
| firstEffect: ?Fiber, | ||
| lastEffect: ?Fiber, |
There was a problem hiding this comment.
Do we need the firstEffect field on every node? It seems like we could make lastEffect point to the root or a placeholder instead of being null and then save a field.
There was a problem hiding this comment.
Any node can end up being reused and then you need the start of that slice of the list.
We could potentially make them non-nullable for type purposes. I'll have to think about that some more. Would pointing to the root by you anything more than pointing to any random placeholder fiber?
For context, a parent can schedule itself before or after its children. That's a feature I take advantage of in subsequent diffs.
There was a problem hiding this comment.
No, no reason to use the root.
What do you mean, "Any node can end up being reused and then you need the start of that slice of the list."?
There was a problem hiding this comment.
If the work on a bunch of parents was aborted, because a higher priority update touched them, we can still reuse the work done on a child that wasn't touched. But we need to know which side-effects it had - separately from the aborted work.
This adds tracking of side-effects that gets scheduled during an update. As the tree gets reconciled, the side-effectful fibers are linked together in an ordered singly linked list. That way we can walk the linked list to commit only the work that needs to be synchronous - quickly. We also store first and last nodes within a fiber. That way when we reuse an already processed subtree, we can reuse that subset of the linked list.
This just makes them instantiable so that we can get access to the host config in these.
This creates a new API for processing side-effects on the host environment. During initial reconciliation host instances are created during the time sliced periods. During updates there is an opportunity for the host to prepare something on the instance during the time slicing, and to determine whether there were any changes. The could be thrown away. At the commit phase, these changes are finally committed to the host instance.
This updates the host container root with new children. Currently, this is always called for updates because we don't track if any children reordered.
This is only for host nodes so that the DOM tree is fully updated by the time we've flushed. Classes will schedule their life-cycles *after* their children's side-effects.
| */ | ||
|
|
||
| /** | ||
| * This is a renderer of React that doesn't have a render target output. |
|
👍 |
| if (!child) { | ||
| return; | ||
| } | ||
| if (child.tag === TERMINAL_TAG) { |
There was a problem hiding this comment.
I'm not really happy with this model of determining terminalness by testing the host environment's type. I'd like to structure the output so that I always know if the next value is terminal or not.
One thing I could do is skip the propagation of single values up the tree and just output the child for those cases. More to traverse but you have to do it at some point I guess. Then I'd just check if the tag is a host node and if so, then I know the output is terminal.
@spicyj Any ideas?
[Fiber] Host Side Effects (cherry picked from commit cf259a4)
This adds a linked list of side-effects and calls the host environment with those side-effects after a tree
has fully reconciled.
Also a rudimentary DOM renderer.
Review individual commits.