Closure leaks
A closure is a function that captures variables from its enclosing scope. The entire captured binding stays alive while the function is reachable.
flowchart TD cb[callback array] fn1["() => huge.length"] huge[huge array 40k items] cb --> fn1 fn1 --> huge
You only “use” huge.length — but the closure captures huge, not just .length.
Broken code
Section titled “Broken code”const handlers = [];
function registerRow(row) { const hugeContext = buildReportForAllRows(); // MB of data handlers.push(() => formatCell(row, hugeContext));}Every handler retains the full hugeContext.
Fixed code
Section titled “Fixed code”function registerRow(row, reportSlice) { handlers.push(() => formatCell(row, reportSlice));}
// Or compute per-row data outside the closurefunction registerRow(row) { const slice = extractSliceFor(row.id); handlers.push(() => formatCell(row, slice));}Live demo
Section titled “Live demo”Live demo: closure over large scope
Small callbacks retain an entire large array via closure.
`performance.memory` is only available in Chromium-based browsers. Use Chrome for live heap readouts.