过去几天我一直在制作这个应用程序,它是一个实时图表。 它工作得很好,但我的问题是性能,如果我让页面打开大约一分钟,在 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:英语不是我的母语,所以如果有任何重大错误,我深表歉意!
最佳答案
是的,不久前我确实遇到了同样的问题。
1。使用新数据更新图表而不是重新绘制
无需重新绘制图表,只需使用 addPoint
推送数据即可。看起来您已经这样做了,但尝试删除 chart.redraw()
调用。您可能必须使用 setExtremes()
调整 x 刻度以包含新的时间戳。
2。对socket.io使用后台 worker (SharedWorker)
我在 Chrome 中做了很多分析(使用时间线功能),结果发现 socket.io 是这里的瓶颈。它不断阻塞 UI 线程,并且堆不断增长,直到浏览器崩溃。
我想出的解决方案是使用SharedWorker将socket.io连接移动到后台线程。 (不是 WebWorker,因为它变得空闲并且不响应套接字连接)。
因此,当您的应用程序启动时,启动一个工作线程,连接到您的套接字。然后,每当工作人员收到消息时,就使用 postMessage
将其发送到您的应用程序。
我发现这种方法带来了巨大的性能提升。
在 Chrome 中,您可以使用 chrome://inspect/#workers
检查工作线程
关于javascript - 性能问题 highchart 图和 socket.io,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36901042/