I’m seeing a behavioral change in Suspense + React.lazy rendering order when upgrading from React 18.3.1 to React 19.x.
Specifically:
React 18.3.1: Components render once, in order:
CompA → CompB → CompC → CompD
React 19.1.0: Still renders cleanly in order (same as 18.3.1).
React 19.2.0: Rendering order changes significantly, and components render multiple times in progressive batches, producing logs like:
CompA
CompB
CompA
CompB
CompC
CompA
CompB
CompC
CompD
This occurs even in production build, and without StrictMode.
Splitting each component into its own Suspense boundary restores the expected behavior.
This appears to be caused by a change in Suspense reveal / pre-warm scheduling between 19.1 and 19.2 — but I'm not sure if this is an intended change, an edge case, or a regression.
I'm opening this issue to confirm:
- Is this new repeated rendering behavior expected in 19.2?
- Is there documentation on the Suspense behavior change between 19.1 and 19.2?
- Should a single Suspense boundary cause repeated re-renders for sibling lazy components in this minimal case?
Minimal Reproduction
Reproduction environment
React versions tested:
18.3.1
19.1.0
19.2.0
Build: Production build
Mode: No StrictMode
Bundler: any (Vite/Webpack tested) — same results
Browser: Chrome stable
Code Example (minimal)
App.tsx
import { lazy, Suspense } from "react";
const CompA = lazy(() => import("./CompA"));
const CompB = lazy(() => import("./CompB"));
const CompC = lazy(() => import("./CompC"));
const CompD = lazy(() => import("./CompD"));
export default function App() {
return (
<div>
<Suspense fallback={null}>
<CompA />
<CompB />
<CompC />
<CompD />
</Suspense>
</div>
);
}
CompA.tsx (same for B/C/D)
const CompA = () => {
console.log("CompA");
return <div>CompA</div>;
};
export default CompA;
Output logs
React 18.3.1
React 19.1.0
React 19.2.0
CompA
CompB
CompA
CompB
CompC
CompA
CompB
CompC
CompD
Additional Observation
If I change the code to one Suspense per component:
<div>
<Suspense fallback={null}><CompA /></Suspense>
<Suspense fallback={null}><CompB /></Suspense>
<Suspense fallback={null}><CompC /></Suspense>
<Suspense fallback={null}><CompD /></Suspense>
</div>
Then React 19.2 logs return to normal:
This strongly suggests the repeated-render behavior is tied to shared sibling Suspense trees.
Questions for the React team
- Is the repeated, interleaved rendering behavior in React 19.2 an intentional Suspense change?
- Is this part of the new "pre-warm / batched reveals" behavior introduced in React 19?
- Should this happen even in a minimal tree where each component only does a static lazy import?
- Is this considered a regression, or should apps rely on separate Suspense boundaries to avoid this?
I’m seeing a behavioral change in Suspense + React.lazy rendering order when upgrading from React 18.3.1 to React 19.x.
Specifically:
React 18.3.1: Components render once, in order:
CompA → CompB → CompC → CompD
React 19.1.0: Still renders cleanly in order (same as 18.3.1).
React 19.2.0: Rendering order changes significantly, and components render multiple times in progressive batches, producing logs like:
This occurs even in production build, and without StrictMode.
Splitting each component into its own Suspense boundary restores the expected behavior.
This appears to be caused by a change in Suspense reveal / pre-warm scheduling between 19.1 and 19.2 — but I'm not sure if this is an intended change, an edge case, or a regression.
I'm opening this issue to confirm:
Minimal Reproduction
Reproduction environment
React versions tested:
18.3.1
19.1.0
19.2.0
Build: Production build
Mode: No StrictMode
Bundler: any (Vite/Webpack tested) — same results
Browser: Chrome stable
Code Example (minimal)
App.tsx
CompA.tsx (same for B/C/D)
Output logs
React 18.3.1
React 19.1.0
React 19.2.0
Additional Observation
If I change the code to one Suspense per component:
Then React 19.2 logs return to normal:
This strongly suggests the repeated-render behavior is tied to shared sibling Suspense trees.
Questions for the React team