react icon indicating copy to clipboard operation
react copied to clipboard

[React 19] Disabling prerendering siblings of suspended components breaking common pattern

Open ehellman opened this issue 8 months ago • 27 comments

Summary

I'm creating this issue to continue the discussion that spawned in the already merged PR (#26380)

Several community members have raised concerns about this change and it has gained traction on both X and Reddit as well, I think it is important to prioritize this discussion as it can be a dealbreaker whether or not a project will upgrade to React 19 at all of this is not addressed.

The problem

This change causes sibling components of suspended components to not prerender, meaning that it will cause performance problems when using a very common pattern where you do data fetching near to where the data is actually used. It makes requests that would before be performed in parallel due to prerendering triggering them, into waterfall requests instead. Here's screenshots from @matiasngf and part of their description from the pull request comment:

First, we recorded the current approach; it takes about 2.5 seconds to load the .glb models:

image

Then, we installed the canary version of react; Same .glb models, takes about 3.5 seconds to load:

image

I included the above example in the issue body because it is a great illustration of the problem. Their comment also include links to both their current site that doesn't have the problem and also a version of their site with an updated React with the problem present.

Discussions around potential fixes

There are several ways to approach this, but I think @matiasperz were spot on when suggesting that this entire change be opt-in. The changed logic seems like the part that should be opt-in, and the default behavior should be the way things worked before the change.

Something along the lines of: strategy={"parallel" | "sequential"} where it is clear how suspended components will behave.

Conclusion

While not exactly a breaking change in the literal sense, I would personally consider this a breaking change and worse, one that it is not possible to easily migrate away from without changing the entire data fetching pattern for your application. The other option being just eating the performance loss but no one is realistically going to do that.

Moving data fetching up is not a good recommendation, since it goes against an extremely common and well-liked pattern in the community and the great thing about React has always been that we can choose our own patterns and develop amazing applications in several different ways. But changes like this, if you cannot opt-out of them (or in this case opt-in, because considering the effects it will have the sensible default should be the previous behavior) would break this very fundamental value of React.

Let's please continue to discuss this to find a good path forward.

ehellman avatar Jun 14 '24 13:06 ehellman