React: Suspense and flash of white screen

Created on 14 Dec 2018  路  2Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?

I guess bug, but this is not stable feature, so not sure

What is the current behavior?

Here is the classical issue with async components in React.

When React application boots (ReactDOM.render) and some components are not loaded, it will flush current available components, which can be some loader or empty screen (null). If there was some HTML before (SSR or prerendered with react-snap) user will see flash of white screen.

filmstrip 3

I expected that Suspense would solve this issue, because it suppose to pause rendering. So I hopped it will not flush placeholder while it waits for subcomponent to load.

On the other side - I know that Suspense and asynchronous rendering is not finished yet, so I hope it will be fixed in the future.

Demo: https://github.com/stereobooster/react-async-issue

Steps:

git clone [email protected]:stereobooster/react-async-issue.git
cd react-async-issue
yarn
# remove homepage from package.json otherwise it will not work locally
yarn build
npx serve -s build

Or you can check online version https://stereobooster.github.io/react-async-issue/

What is the expected behavior?

I expect that Suspense will pause rendering of React until maxDuration times out or all components get loaded (whatever comes first), and before this no DOM changes would be flushed.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React 16.6.3. Feature is fresh so no sense to check in previous versions.

Most helpful comment

The "pausing" feature of Suspense is only enabled in Concurrent Mode, which has not been released yet. In Concurrent Mode, it will behave the way you have described. You can learn more about our roadmap here: https://reactjs.org/blog/2018/11/27/react-16-roadmap.html

All 2 comments

The "pausing" feature of Suspense is only enabled in Concurrent Mode, which has not been released yet. In Concurrent Mode, it will behave the way you have described. You can learn more about our roadmap here: https://reactjs.org/blog/2018/11/27/react-16-roadmap.html

Yes I thought so (but secretly hopped I'm doing it wrong). I also tried React.unstable_ConcurrentMode and ReactDom.unstable_createRoot. Oh well... let's wait.

Thank you

UPD

After poking around, it seems I found solution (which is marked as unstable).

const ConcurrentMode = React.unstable_ConcurrentMode;
const Root = (
  <ConcurrentMode>
    <Suspense fallback={null} maxDuration={5000}>
      <App />
    </Suspense>
  </ConcurrentMode>
);

const rootElement = document.getElementById("root");
const root = ReactDom.unstable_createRoot(rootElement);
root.render(Root);

The problem was, that before I tried separately React.unstable_ConcurrentMode and unstable_createRoot, but not together.

filmstrip-concurent

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebmarkbage picture sebmarkbage  路  136Comments

gaearon picture gaearon  路  227Comments

robdodson picture robdodson  路  129Comments

iammerrick picture iammerrick  路  94Comments

acdlite picture acdlite  路  83Comments