过去几天我一直在制作这个应用程序,这是一个实时图表。 它运行得很好,但我的问题是性能,如果我让页面打开大约一分钟,ram的使用量几乎达到了gig(!),之后chrome运行垃圾收集器(我假设)。 我认为这是因为我每次更新系列时都会重新绘制图表(我相信每5秒钟),但我真的不知道如何修复它。 这是我的代码:
$(document).ready(function() {
var socket = io.connect();
socket.emit('requestStockData');
Highcharts.setOptions({
global: {
useUTC: false
}
});
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
defaultSeriesType: 'spline',
events: {
load: function() {
var chart = this;
loadChart(chart);
}
}
},
title: {
text: ''
},
xAxis: {
type: 'datetime',
tickInterval: 300 * 1000
},
yAxis: {
title: {
text: 'Prix en €'
}
}
});
function update(chart) {
socket.on('_sbourse', function(rawArray) {
for (var i = 0; i < rawArray.length; i++) {
var entry = rawArray[i];
var id = entry.id;
var str = entry.timestamp.toString();
var time = str.slice(0, -3);
var array = [
[parseInt(time), entry.price]
];
var array_to_point = [parseInt(time), entry.price];
$.each(chart.series, function(i, v) {
serieId = chart.series[i].options.id;
if (serieId == id) {
chart.series[i].addPoint([parseInt(time), entry.price], false);
}
});
}
chart.redraw(true);
});
}
function loadChart(chart) {
var array = {};
socket.on('stockData', function(rawArray) {
for (var i = 0; i < rawArray.length; i++) {
var entry = rawArray[i];
var id = entry.id;
var str = entry.timestamp.toString();
var time = str.slice(0, -3);
var array = [
[parseInt(time), entry.price]
];
var array_to_point = [parseInt(time), entry.price];
if (i < 18) {
chart.addSeries({
name: entry.name,
id: entry.id,
data: array
});
} else {
$.each(chart.series, function(i, v) {
serieId = chart.series[i].options.id;
if (serieId == id) {
chart.series[i].addPoint([parseInt(time), entry.price], false);
}
});
}
}
chart.redraw(true);
});
update(chart);
}
});
所以,是的,我想知道你们其中一个人是否已经遇到过这个问题并且已经解决了这个问题 PS:英语不是我的第一语言,所以如果有任何重大错误我会道歉!
答案 0 :(得分:2)
是的,我不久前遇到了同样的问题。
只需使用addPoint
推送数据,而不是重新绘制图表。看起来你已经这样做但是尝试删除chart.redraw()
电话。您可能必须使用setExtremes()
来调整x比例以包含新的时间戳。
我在Chrome中进行了大量的分析(使用时间轴功能),结果发现socket.io是这里的瓶颈。它不断阻塞UI线程,堆只会不断增长,直到浏览器崩溃。
我想出的解决方案是将socket.io连接移动到后台线程,使用SharedWorker(不是WebWorker,因为它变为空闲且不响应套接字连接)。
因此,当你的应用程序启动时,启动一个worker,连接到你的socket。然后,只要工作人员收到消息,请使用postMessage
将其发送到您的应用程序。
我看到这种方法带来了巨大的性能提升。
在Chrome中,您可以使用chrome://inspect/#workers