Common Causes of JavaScript Memory Leaks

JavaScript garbage-collects automatically, but that only works if nothing still references an object you meant to discard — a handful of common patterns quietly keep references alive far longer than intended.

// 1. Forgotten event listeners on removed elements
element.addEventListener('click', handler);
element.remove(); // the listener (and its closure) may still be referenced elsewhere

// 2. Timers that are never cleared
const interval = setInterval(() => updateData(), 1000);
// component unmounts, but the interval keeps running and referencing it forever
// FIX: clearInterval(interval) on cleanup

// 3. Growing caches/maps with no eviction
const cache = new Map();
function memoize(key, value) {
    cache.set(key, value); // grows forever if keys are never removed
}

// 4. Closures capturing more than they need
function setupHandler(hugeDataset) {
    return () => console.log('clicked'); // still holds a reference to hugeDataset
                                            // even though it never uses it!
}

Chrome DevTools’ Memory tab (specifically, comparing heap snapshots taken before and after an action that should release memory) is the definitive way to confirm a suspected leak rather than guessing from symptoms alone.