Skip to main content

Garbage collection pauses under 50ms

ab-002033 · performance-deep-dive.runtime-memory.gc-pauses-under-50ms
Severity: mediumactive

Why it matters

A GC pause of 250ms during a scroll or animation freezes the frame pipeline: no input events are processed, no pixels are painted. Users experience this as a sudden hard stutter that is qualitatively worse than slow load times. ISO 25010:2011 time-behaviour captures the latency; the GC pressure that produces long pauses is typically caused by allocating large arrays or objects inside render loops or scroll handlers — code patterns that generate garbage faster than incremental GC can collect it.

Severity rationale

Medium because GC pauses over 50ms produce visible jank during animations and scrolling, but the impact is intermittent and depends on workload and device memory, making it a degraded-experience issue rather than a blocking failure.

Remediation

Move expensive computations out of render loops using useMemo or useCallback. For server-side Node.js services, use clinic.js to identify GC pressure hotspots.

// components/dashboard.tsx — memoize to reduce GC pressure in render
const processedRows = useMemo(
  () => rawData.map((row) => transformRow(row)),  // runs once per rawData change
  [rawData]
)

For scroll handlers, avoid creating new arrays or objects inside the callback — pre-allocate or reuse structures.

Detection

  • ID: performance-deep-dive.runtime-memory.gc-pauses-under-50ms

  • Severity: medium

  • What to look for: Count all locations where large arrays or objects are created in hot paths (render loops, scroll handlers). Use Chrome DevTools Performance tab or Node.js profiler to measure GC pause times. Look for gaps in event execution. For Node.js backend, use clinic.js or Node.js --inspect profiler.

  • Pass criteria: GC pauses are under 50ms during typical user workloads. No frame drops due to GC.

  • Fail criteria: GC pauses exceed 50ms, causing visible jank or frame drops.

  • Skip (N/A) when: The application is a static site with no dynamic JavaScript.

  • Cross-reference: For animation frame budget that depends on GC pauses, see animation-frame-budget.

  • Detail on fail: "GC pause spike to 250ms during dashboard render — causes frame drops and janky scrolling"

  • Remediation: Reduce memory pressure by avoiding large object allocations in hot loops. Use object pools for frequently-created objects.

    // components/dashboard.tsx — use useMemo to avoid GC pressure
    const processedData = useMemo(() => heavyComputation(data), [data])
    

External references

Taxons

History