Skip to content

Bug: Massive memory allocations using React dev build under frequent updates (prod build unaffected) #34770

@dokugo

Description

@dokugo

React dev build has a memory issue where under frequent updates memory footprint grows from ~100 MB to 1 GB within 5 minutes in a simple reproduction app. The JS heap remains stable at ~50 MB. Production builds are unaffected. Or I might have introduced a bug which is reproducible in dev only.

Reproduce

  1. Run: https://github.com/dokugo/react-dev-memory-leak
    This repo replicates behavior I have in one of my apps. It's a virtualized table with 400 rows and 10 cols. Every second the last row is removed and one new row is prepended. Also a random 50% of total cells are updated and re-rendered (increased the amount for faster reproduction).

  2. Do nothing and wait a few minutes, see "memory footprint" in Chrome task manager, or "memory" in Firefox about:processes grow from ~100MB to 1GB in a few minutes, while actual JS memory heap stays lean and stable.

  3. While app is running: Chrome DevTools > Memory > Allocation instrumentation on timeline (Allocation stack traces checked). Allocation timeline points to React internals, probaby their allocations aren't promptly GC'd. Perhaps some dev mode instrumentation? Or maybe has something to do with detached nodes?

  4. See top offenders (all from react-dom-client.development.js). Data from the screenshot below:

  • addValueToProperties > addObjectDiffToProperties: 20 million objects allocated, +610MB
  • logComponentRender > commitPassiveMountOnFiber, recursivelyTraversePassiveMountEffects: 3.9M obj, 186MB
  • repeat > addValueToProperties > addObjectDiffToProperties: 8.9M obj, 156MB

All of them showing tiny Live Size, but the actual memory footprint of the tab actively grows with them allocating more, until we hit OOM.

Screenshot and profile of what happens in 5 min of running dev server:
https://drive.proton.me/urls/300AVT1D3R#obxPg3RRxZQE
Image

Screenshot and profile of memory allocations over 5 minutes for the PlainTable variation (incognito, no extensions):
https://drive.proton.me/urls/M75DRSHMWM#6kCT7t1TazyP
Image

Notes:

  • I use React Compiler with a bit of manual memoization, using fully manual memoization still reproduces the bug
  • Reproduces using PlainTable.tsx (no TanStack Table and Virtualizer)
  • Reproduces with disabled React Scan and React DevTools
  • Reproduces with and without StrictMode
  • Reproduces in incognito with extensions disabled and DevTools closed
  • Production build works without issues
  • React 19.2.0 with Vite
  • In my app I have 2 tables with sometimes 1000+ rows in each one (with 15-20 cols), consuming 100-1000 WebSocket updates per second, batching them and applying mutation to TanStack Query cache once per second. Memory allocation grows from 300MB to 3GB unacceptably fast, making development difficult. Yet in production no issues, small and stable memory footprint, no lags, while my cells have a lot inside them, including frequent animations, images...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: UnconfirmedA potential issue that we haven't yet confirmed as a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions