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
Store interleaved updates on separate queue until end of render (#20615)
## Motivation
An *interleaved* update is one that is scheduled while a render is
already in progress, typically from a concurrent user input event.
We have to take care not to process these updates during the current
render, because a multiple interleaved updates may have been scheduled
across many components; to avoid tearing, we cannot render some of
those updates without rendering all of them.
## Old approach
What we currently do when we detect an interleaved update is assign a
lane that is not part of the current render.
This has some unfortunate drawbacks. For example, we will eventually run
out of lanes at a given priority level. When this happens, our last
resort is to interrupt the current render and start over from scratch.
If this happens enough, it can lead to starvation.
More concerning, there are a suprising number of places that must
separately account for this case, often in subtle ways. The maintenance
complexity has led to a number of tearing bugs.
## New approach
I added a new field to the update queue, `interleaved`. It's a linked
list, just like the `pending` field. When an interleaved update is
scheduled, we add it to the `interleaved` list instead of `pending`.
Then we push the entire queue object onto a global array. When the
current render exits, we iterate through the array of interleaved queues
and transfer the `interleaved` list to the `pending` list.
So, until the current render has exited (whether due to a commit or an
interruption), it's impossible to process an interleaved update, because
they have not yet been enqueued.
In this new approach, we don't need to resort to clever lanes tricks to
avoid inconsistencies. This should allow us to simplify a lot of the
logic that's currently in ReactFiberWorkLoop and ReactFiberLane,
especially `findUpdateLane` and `getNextLanes`. All the logic for
interleaved updates is isolated to one place.
0 commit comments