Skip to content

Bug: Suspense + React.lazy rendering order regression between React 18.3.1 → 19.1.0 → 19.2.0 (unexpected repeated renders in 19.2) #35211

@Darshan-Naik

Description

@Darshan-Naik

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

CompA
CompB
CompC
CompD

React 19.1.0

CompA
CompB
CompC
CompD

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:

CompA
CompB
CompC
CompD

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Resolution: StaleAutomatically closed due to inactivityStatus: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions