diff --git a/packages/react-dom-bindings/src/client/ReactDOMHostConfig.js b/packages/react-dom-bindings/src/client/ReactDOMHostConfig.js index 253b2da401cc8..8475755904946 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMHostConfig.js +++ b/packages/react-dom-bindings/src/client/ReactDOMHostConfig.js @@ -3343,6 +3343,13 @@ export function waitForCommitToBeReady(): null | (Function => Function) { } function unsuspendAfterTimeout(state: SuspendedState) { + // We almost never want to show content before its styles have loaded. But + // eventually we will give up and allow unstyled content. So this number is + // somewhat arbitrary — big enough that you'd only reach it under + // extreme circumstances. + // TODO: Figure out what the browser engines do during initial page load and + // consider aligning our behavior with that. + const stylesheetTimeout = 60000; // one minute setTimeout(() => { if (state.stylesheets) { insertSuspendedStylesheets(state, state.stylesheets); @@ -3352,7 +3359,7 @@ function unsuspendAfterTimeout(state: SuspendedState) { state.unsuspend = null; unsuspend(); } - }, 500); + }, stylesheetTimeout); } function onUnsuspend(this: SuspendedState) { diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index d089b25ffad03..d362e1b94a4a9 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -3163,7 +3163,7 @@ body { ); }); - it('can unsuspend after a timeout even if some assets never load', async () => { + it('stylesheets block render, with a really long timeout', async () => { function App({children}) { return ( @@ -3191,7 +3191,22 @@ body { , ); - jest.advanceTimersByTime(1000); + // Advance time by 50 seconds. Even still, the transition is suspended. + jest.advanceTimersByTime(50000); + await waitForAll([]); + expect(getMeaningfulChildren(document)).toEqual( + + + + + + , + ); + + // Advance time by 10 seconds more. A full minute total has elapsed. At this + // point, something must have really gone wrong, so we time out and allow + // unstyled content to be displayed. + jest.advanceTimersByTime(10000); expect(getMeaningfulChildren(document)).toEqual(