facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
227.82k stars 46.51k forks source link

Bug: `use()` Delays Loading in Unrelated Components, Suspense Waits for Unrelated `use()` Calls #28070

Open PutziSan opened 8 months ago

PutziSan commented 8 months ago

React version: experimental (0.0.0-experimental-e1d20fc0c-20240122)

Steps To Reproduce

Link to code example: https://codesandbox.io/p/sandbox/react-use-repro-jq8zqs

To reproduce the issue, render multiple components as siblings within a React application. Each component includes a Suspense boundary and uses the use() hook for data loading. There are two types of components involved:

Each component loads data two times from a fake API with different arguments. Each fake API call takes 1 second to complete. So the parallel loading components should render after 1 second, and the sequential loading components should render after 2 seconds.

The data loading is cached:

async function doFakeFetch(data) {
  // wait 1 second so that we can see the loading state
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return "loaded - " + data;
}

const cache = new Map();
export function loadData(data) {
  if (!cache.has(data)) {
    cache.set(data, doFakeFetch(data));
  }
  return cache.get(data);
}

The current behavior

Currently, only the first child component (UseExampleParallel) displays after 1 second. All other children components delay their rendering until all promises are resolved, leading to a total rendering time of about 5 seconds for all components. Consequently, the entire application ends up rendering after about 5 seconds, regardless of the mix of parallel and sequential components.

The expected behavior

In the expected scenario, each UseExampleParallel component should render after approximately 1 second, and each UseExampleSequential component should render after approximately 2 seconds. Overall, the complete application is expected to render after roughly 2 seconds.

Further Information

Observations show that when only parallel components are used, the app's loading time remains around 1 second. However, with the addition of sequential components, each additional component increases the app's loading time by 1 second.

Additionally, parallel loading components (other than the first child) also wait for sequential components to finish loading before displaying their content.

It seems to me, that the problem only appears, if data is loaded in a component which is inside a Suspense boundary. If the data is loaded outside the Suspense boundary and passed as props to the component, the problem does not appear.

github-actions[bot] commented 5 months ago

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

PutziSan commented 5 months ago

Bump

github-actions[bot] commented 2 months ago

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

eps1lon commented 2 months ago

Sounds like the same issue as https://github.com/facebook/react/issues/29905?