【问题标题】:DOM Node count increase when loading Highcharts documents (Chrome)加载 Highcharts 文档时 DOM 节点数增加 (Chrome)
【发布时间】:2013-09-18 02:21:21
【问题描述】:

我有一个网页可以定期加载 Highcharts 图表 - 就像循环播放幻灯片一样。我的问题是,在 Chrome 中运行网络几个小时后(其他浏览器目前不是一个选项)会崩溃,并显示“哦,快!显示此网页时出现问题。”

使用“Chrome 开发工具->Timeline”我可以看到“DOM Node Count”不断增加。(也是文档数)。

这是更大网络的一部分,因此我无法发布代码。但是,我创建了一个以类似方式执行操作的页面。我用 JQuery.load() 加载图表。

当旋转纯 HTML 页面时,DOM 计数不会增加(被垃圾收集)。

请有人告诉我我做错了什么?我可以用不同的方式做到这一点吗?这是一个 Highcharts 错误吗?任何有关如何解决此问题的建议。

这里有一些可以产生这种行为的代码。 (对不起,我无法让它在 jsfiddle 中工作) (“$(document).ready”函数中的注释和取消注释以在加载方法之间切换)

我已经把这个页面放在这里了:http://memoryleak.ivarragnarsson.com,您可以在其中选择查看泄漏的 Highcharts 版本或标准的 HTML 加载非泄漏版本。

“memoryleak.html”

<html>
<head>
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.src.js"></script>

    <script type="text/javascript">
        function UpdateGraphsDiv()
        {
        if (typeof window.chart != 'undefined')
        {
            window.chart.destroy();
        }

            $.ajaxSetup({ cache: false, async: false });
            $("#chartcontainer").load("graph.html");
        }

        $(document).ready(function ()
        {
            UpdateGraphsDiv(); setInterval(UpdateGraphsDiv, 5000);  //Updates graph in div using JQuery Load
        });


    </script>
</head>
<body>
<div id="chartcontainer"></div>
</body>
</html>

"graph.html"

<div id='container1' style='min-width: 310px; height: 400px; margin: 0 auto'></div>
    <script type='text/javascript'>
    $(function ()
    {
        $('#container1').highcharts({
            chart: {
                type: 'column'
            },
            title: {
                text: 'Monthly Average Rainfall'
            },
            subtitle: {
                text: 'Source: WorldClimate.com'
            },
            xAxis: {
                categories: [
                'Jan',
                'Feb',
                'Mar',
                'Apr',
                'May',
                'Jun',
                'Jul',
                'Aug',
                'Sep',
                'Oct',
                'Nov',
                'Dec'
            ]
            },
            yAxis: {
                min: 0,
                title: {
                    text: 'Rainfall (mm)'
                }
            },
            tooltip: {
                headerFormat: '<span style=""font-size:10px"">{point.key}</span><table>',
                pointFormat: '<tr><td style=""color:{series.color};padding:0"">{series.name}: </td>' +
                '<td style=""padding:0""><b>{point.y:.1f} mm</b></td></tr>',
                footerFormat: '</table>',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderWidth: 0
                }
            },
            series: [{
                name: 'Tokyo',
                data: [49.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]

            }, {
                name: 'New York',
                data: [83.6, 78.8, 98.5, 93.4, 106.0, 84.5, 105.0, 104.3, 91.2, 83.5, 106.6, 92.3]

            }, {
                name: 'London',
                data: [48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 65.2, 59.3, 51.2]

            }, {
                name: 'Berlin',
                data: [42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 47.6, 39.1, 46.8, 51.1]

            }]
        });
    });
    </script>
</div>

请告诉我如何阻止这种 DOM 节点的堆积。

【问题讨论】:

  • 使用$("#divpagediv").html(''); 代替.empty(); 有帮助吗?
  • 不幸的是它并没有改变任何东西。不过感谢您的想法。
  • 我几乎可以肯定这不是你的代码,听起来更像是 highcharts 保持对死节点的引用并且它正在泄漏
  • 在同一个 div 中重新创建图表之前,请确保您之前调用过 chart.destroy()
  • 谢谢帕维尔。我按照您的建议稍微更改了代码。 DOM 计数仍然随着每次新加载(JQuery)而增加,但速度要慢得多。 (2-4 个 DOM 对象公关新加载)。我还没有确定泄漏的来源(即可能是 JQuery 的 Highcharts?)

标签: javascript jquery memory-leaks highcharts


【解决方案1】:

按照约定,调用chart.destroy() 解决了大部分DOM 节点增加的问题。根据 Ivar 的示例,我可以看到它不依赖于 Highcharts(见附表) - 看起来 jQuery.load() 没有正确清理以前的内容。

左:无图表 ||右:附图表

【讨论】:

  • 感谢您抽出宝贵时间 Pawel。我看到你不在窗户上。当我在 Windows 上进行这些测试时,“Chrome 版本 29.0.1547.76 m”页面上的 DOM 节点计数总是在收集垃圾时变为 271。谁能证实这一点? (它稳定在 293 但我在 load() 前面添加了一个 $("#chartcontainer").html('') - 在 Highcharts 页面上进行相同的更改并没有改变 DOM 节点的不断增加)
  • 试过 Ivar 的例子 (memoryleak.ivarragnarsson.com/nomemoryleak.html) 并且在垃圾收集之后节点计数总是再次下降。所以没有内存泄漏。 (铬 v29.0.1547.66)。我还注意到 Highcharts 的这种内存(节点)泄漏。
  • 已确认 - 只需使用超过 15 分钟即可看到内存泄漏。
  • 运行测试 1.5 小时。节点数总是下降,如图所示Here
  • 我已经进行了相当多的测试并得出结论,在 Highcharts 重新加载页面的情况下,chrome devtool 会保留 DOM 节点。当一个人停止并启动时间线记录器时,节点数会下降。感谢 Pawel 的回答...
【解决方案2】:

如果您不需要 HighCharts 的动态交互部分。然后我会使用 PhantomJS Webserver 创建图表的图像。然后将图表图像加载到您的 div 中。这样,HighCharts 库就不会消除客户端交互的负载。

使用 PhantomJS 非常简单地创建 HighCharts。

http://www.highcharts.com/component/content/article/2-news/56-improved-image-export-with-phantomjs

【讨论】:

    猜你喜欢
    • 2014-04-24
    • 2016-05-10
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2011-03-14
    • 2015-02-24
    相关资源
    最近更新 更多