Skip to content

CONCEPT Cited by 1 source

JavaScript heap size

JavaScript heap size is the memory the browser's JS engine (V8 in Chromium / Edge, SpiderMonkey in Firefox, JavaScriptCore in Safari) allocates for JS objects, closures, and arrays on a page. Distinct from the DOM (concepts/dom-node-count) which is allocated by the layout engine — both live in the tab's process but grow from different sources.

Why it matters

  • Per-tab ceiling: browsers cap heap at roughly 1-4 GB per renderer process; exceeding it crashes the tab.
  • GC pauses scale with heap size: a larger heap means longer stop-the-world pauses during full GC, spiking tail latency on the main thread. This directly affects INP.
  • Cross-site cost: on mobile, competing tabs + OS constraints can evict a tab that's using >500 MB of heap.
  • OOM manifests as unresponsive page / tab crash — not a graceful degradation path.

Sources of heap growth in rich UIs

  1. Component instances and their state. Each React / Vue / Angular component instance keeps its hooks, closures, refs, and props in the heap. Long lists of components multiply this cost.
  2. Event handlers and their closures. Every closure retains its capture set — if handlers capture large objects, the objects stay resident.
  3. Cached / accumulated data. API response caches, scroll buffers, undo histories.
  4. Large strings / source maps / blob data accumulated by tooling libraries.

Measurement

  • Chrome DevTools Memory tab — heap snapshots + allocation profiler.
  • performance.memory.usedJSHeapSize (deprecated but widely supported in Chrome) for RUM-style reporting.
  • Memory tagging in RUM dashboards: attribute each user session's heap growth to the feature / route it happened on. GitHub's Datadog dashboard tags heap against PR-size buckets (systems/github-pull-requests).

Canonical wiki instance

GitHub's Files-changed tab on extreme-tail PRs: JS heap >1 GB (pre-optimization). On the published 10,000-line split-diff benchmark:

  • v1: 150-250 MB
  • v2: 80-120 MB (~50 % less)
  • p95+ virtualized: 10× reduction vs pre-virtualization

The v2 memory win was driven by the React runtime layer (components + state + handlers) shrinking 74 %, despite the DOM only shrinking 10 % — i.e. most of the heap cost was React's component tree, not the DOM itself.

Server-side analogue

At the process level, server-side runtimes have the same RSS-vs- committed-vs-in-use distinction: see concepts/go-runtime-memory-model for the Go 1.24 regression case where virtual heap was stable but resident memory spiked. The same "which metric am I actually reading?" lesson applies — browsers' performance.memory reports V8's allocated heap, not necessarily the page's full resident set (renderer-process memory includes DOM, compositor, images, etc.).

Last updated · 200 distilled / 1,178 read