ShadowNode immutability timing #39
-
Please correct me if my understanding here is wrong: When a rerender changes a prop on a component, the JS will call In During the time the background layout is running, what tree is the JS running against? The node that JS got given in cloneNode is still not sealed. Would a rerender with an additional prop change during this time have to reclone the previously commited node? Or does it clone the currently unsealed node - which I would think wouldn't be thread safe at this point since the layout thread could be in the middle of modifying the node? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
I'm also curious about this. Aside from the layout work, there's also native side state being progressed. By inspecting the code, it seems like it's possible that JS works on the uncommitted node. |
Beta Was this translation helpful? Give feedback.
-
Hello @acoates-ms, sorry for the slow reply, I'm on a leave and come to Github sparsely. I'll try to answer your questions but you should know I'm not 100% familiar with JavaScript's implementation but will share my mental model, which may be incomplete. The original design only had two threads, JavaScript thread and the main thread. We had to add additional background thread for layout to match old architecture's performance characteristics on Android. In the future we may look at removal of background thread as it would simplify the threading model.
To clarify, Sealable -> this is just a helper class we use to detect if we try to mutate a shadow node incorrectly. Its implementation does nothing in optimised builds. This concept is not exposed to React.
If a prop changes, the unsealed node is cloned with new props and |
Beta Was this translation helpful? Give feedback.
-
I had Josh explain the thinking here offline. Most code acts off the last committed tree, so things like calls to measure will always get the latest committed node, and those will have layout data set already. Layout data should only be read during/after commit, at which point it should be set. But the cloning can happen before that. -- So yes, during cloning the state of the layout metrics are unknown. No, I haven't hit anything specific. At this point it's more a concern that despite the sealable code which looks like its trying to detect if mutations are happening incorrectly, the protection does not ensure that the node is sealed before additional clones are made. Really the sealable nodes would have to have two types of sealed. One that ensures that the majority of props are sealed, and its safe to clone again. Which should happen before returning from |
Beta Was this translation helpful? Give feedback.
Hello @acoates-ms,
sorry for the slow reply, I'm on a leave and come to Github sparsely.
I'll try to answer your questions but you should know I'm not 100% familiar with JavaScript's implementation but will share my mental model, which may be incomplete.
The original design only had two threads, JavaScript thread and the main thread. We had to add additional background thread for layout to match old architecture's performance characteristics on Android. In the future we may look at removal of background thread as it would simplify the threading model.