Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhide Suspense trees without entanglement #18733

Closed

Commits on May 1, 2020

  1. Unhide Suspense trees without entanglement

    When a Suspense boundary is in its fallback state, you cannot switch
    back to the main content without also finishing any updates inside the
    tree that might have been skipped. That would be a form of tearing.
    
    Before we fixed this in facebook#18411, the way this bug manifested was that a
    boundary was suspended by an update that originated from a child
    component (as opposed to props from a parent). While the fallback was
    showing, it received another update, this time at high priority. React
    would render the high priority update without also including the
    original update. That would cause the fallback to switch back to the
    main content, since the update that caused the tree to suspend was no
    longer part of the render. But then, React would immediately try to
    render the original update, which would again suspend and show the
    fallback, leading to a momentary flicker in the UI.
    
    The approach added in facebook#18411 is, when receiving a high priority update
    to a Suspense tree that's in its fallback state is to bail out, keep
    showing the fallback and finish the update in the rest of the tree.
    After that commits, render again at the original priority. Because low
    priority expiration times are inclusive of higher priority expiration
    times, this ensures that all the updates are committed together.
    
    The new approach in this commit is to turn `renderExpirationTime` into a
    context-like value that lives on the stack. Then, when unhiding the
    Suspense boundary, we can push a new `renderExpirationTime` that is
    inclusive of both the high pri update and the original update that
    suspended. Then the boundary can be unblocked in a single render pass.
    
    An advantage of the old approach is that by deferring the work of
    unhiding, there's less work to do in the high priority update.
    
    The key advantage of the new approach is that it solves the consistency
    problem without having to entangle the entire root.
    acdlite committed May 1, 2020
    Configuration menu
    Copy the full SHA
    9ea9c5f View commit details
    Browse the repository at this point in the history