Ajax reload + Highcharts memory leak?

Ajax reload + Highcharts memory leak?

arosenthalarosenthal Posts: 2Questions: 1Answers: 0

I am trying to create a DataTable that periodically refreshes from Ajax data, where one of the columns is rendered with a Highcharts object. The rendering is working fine, but I am experiencing a memory leak. My memory consumption seems to grow steadily on every call to ajax.reload() and I can't seem to figure out why this is happening.

This is the (much simplified) code I currently have:

$(document).ready(function () {
    $('#table').DataTable({
        ajax: function (data, callback, settings) {
            var table = this.DataTable();
            
            $.get('path/to/ajax').then(function (res) {
                // Transform the response data and pass into the DataTables callback function
                callback(TransformData(res));
                
                // Perform long polling to refresh the DataTable
                setTimeout(function () {
                    table.ajax.reload();
                }, 10000); // time interval = 10s
            })
        },
        columnDefs: [
            {
                targets: 'sparkline',
                createdCell: function (td, cellData, rowData, row, col) {
                    // Create Highcharts sparkline
                    $(td).highcharts('SparkLine', cellData.options);
                }
            }
        ]
    })
});

In my HTML, I'm then defining the table and specifying which columns should be rendered with a Highcharts sparkline (by setting the class to 'sparkline'):

<table id="table" class="display" cellspacing="0" style="width: 720px;">
    <thead>
        <tr>
            ...
            <th class="sparkline" data-orderable="false">Trend</th>
            ...
        </tr>
    </thead>
</table>

Can anyone help me to understand why this is producing a memory leak? My best guess is that the call to ajax.reload() is not fully removing the cells from the DOM, so the Highcharts objects are remaining in memory, but I'm not sure the best way to resolve this if that's the case. Any insight would be appreciated.

Answers

  • allanallan Posts: 63,810Questions: 1Answers: 10,516 Site admin

    If you comment out the HighChart code do you still see the leak?

    My guess is that you need to destroy the old HighCharts. I'm afraid I don't know what their API method is to do that.

    Allan

  • allanallan Posts: 63,810Questions: 1Answers: 10,516 Site admin

    Oh - use preXhr to know when to destroy them.

    Allan

  • arosenthalarosenthal Posts: 2Questions: 1Answers: 0

    Thanks for your feedback. You were right, it turns out I have to manually destroy the Highcharts object before rebuilding the chart. For anyone curious, the following code snippet worked for me to resolve the memory leak:

    ...
    table.cells().every(function () {
        var chart = $(this.node()).highcharts();
        if (chart) chart.destroy();
    });
    
    // Transform the response data and pass into the DataTables callback function
    callback(TransformData(res));
    ...
    
  • allanallan Posts: 63,810Questions: 1Answers: 10,516 Site admin

    Awesome - thanks for posting back. I should have guessed their destroy method would just be destroy(). Makes sense!

    Allan

This discussion has been closed.