#25363·highcharts

Chart's ResizeObserver is never disconnected, leaking memory after destroy

Author: AndrzejBuleczkaCreated Sep 17, 2026Updated Sep 18, 2026
LabelsType: BugProduct: Highcharts

Expected behaviour

The ResizeObserver created in Chart#setReflow should be disconnected when the chart is destroyed, the same way the legacy window.resize fallback in the same method unbinds its listener on the destroy event.

Actual behaviour

The observer is never disconnected, and no reference to it is kept, so there is no way to disconnect it from the outside either.

The observer is never disconnected, and no reference to it is kept:

javascript
// ts/Core/Chart/Chart.ts, Chart#setReflow
if (typeof ResizeObserver === 'function') {
    (new ResizeObserver(runReflow)).observe(chart.renderTo);

// Fallback for more legacy browser versions.
} else {
    const unbind = addEvent(win, 'resize', runReflow);
    addEvent(this, 'destroy', unbind);
}

It holds chart.renderTo and the runReflow closure, which holds the chart. So every chart.destroy() leaves behind an observer, a closure and the gutted Chart, for as long as the container stays reachable, the normal case when the container is reused. Each leaked observer also keeps running runReflow on every container resize.

Reported from production as an out of memory crash in Chromium after 3 days to 3 months, depending on the chart update frequency.

Live demo with steps to reproduce

https://jsfiddle.net/BlackLabel/bezh4yua/ Expected: 0. Actual: 50.

Product version

Highcharts Core 13.0.2

Affected browser(s)

all


Possible fix: keep a reference to the observer and disconnect it on destroy, mirroring the fallback branch:

javascript
const observer = new ResizeObserver(runReflow);
observer.observe(chart.renderTo);
addEvent(this, 'destroy', () => observer.disconnect());

Related: #22636 touches the same branch of setReflow, but is a separate request.