667f9d4fa2
Remove cold derivation reads Prior to this commit, the first render of every `useDerivation()` resulted in a cold read of its inner derivation. Cold reads are predictably slow. The reason we'd run cold reads was to comply with react's rule of not running side-effects during render. (Turning a derivation hot is _technically_ a side-effect). However, now that users are animating scenes with hundreds of objects in the same sequence, the lag started to be noticable. This commit changes `useDerivation()` so that it turns its derivation hot before rendering them. Freshen derivations before render Previously in order to avoid the zombie child problem (https://kaihao.dev/posts/stale-props-and-zombie-children-in-redux) we deferred freshening the derivations to the render phase of components. This meant that if a derivation's dependencies changed, `useDerivation()` would schedule a re-render, regardless of whether that change actually affected the derivation's value. Here is a contrived example: ``` const num = new Box(1) const isPositiveD = prism(() => num.derivation.getValue() >= 0) const Comp = () => { return <div>{useDerivation(isPositiveD)}</div> } num.set(2) // would cause Comp to re-render- even though 1 is still a positive number ``` We now avoid this problem by freshening the derivation (i.e. calling `der.getValue()`) inside `runQueue()`, and then only causing a re-render if the derivation's value is actually changed. This still avoids the zombie-child problem because `runQueue` reads the derivations in-order of their position in the mounting tree. On the off-chance that one of them still turns out to be a zombile child, `runQueue` will defer that particular `useDerivation()` to be read inside a normal react render phase. |
||
---|---|---|
.. | ||
browser-bundles | ||
dataverse | ||
dataverse-experiments | ||
playground | ||
r3f | ||
react |