VUE2 WebSocket 浏览器切换后台之后监听不执行,页面数据堆积造成卡顿,如何解决?
界面上一个表格,一个折线图。
上半部分是个表格,下半部分是一个折线图。
页面初始化时候,界面加载完成,表格与统计图初步绘制。
然后通过WebSocket将后端数据持续推送到前端,前端通过vue2监听数据,将数据更新到element表格与hightcharts统计图。
现在的问题就是,将浏览器切换到后台之后,一段时间后,前端界面将不会渲染,导致界面卡死。
表格是数据替换。代码展示
// 推送数据,监听数据推送
wsData: {
deep: true,
handler: function (newV) {
if (this.tableKeysData.length > 0 && newV.length > 0) {
this.tableData = this.dealTableList(this.tableData, this.getRowKey(newV))
}
}
},
// 数据推送之后,更新当前表格数据,因为推送的是部分字段,所以使用对象合并,将新数据替换原本数据
dealTableList(arr, newList) {
newList.forEach(item => {
const index = arr.findIndex(obj => (obj.paramIdNameChannel == item.paramIdNameChannel));
if (index !== -1) {
arr.splice(index, 1, { ...arr[index], ...item });
}
})
return arr
},
统计图数据超过一千之后会删除最初的点,
// 折线图数据监听
wsData: {
deep: true,
handler: function (newV) {
if (this.chartsKeysData.length > 0 && newV.length > 0) {
newV.forEach(item => {
this.addLineOrPoint(item)
})
}
}
},
// 折线图绘制,数据量大时候删除最初的点
addLineOrPoint(newObj) {
let arr = this.highcharts.series
let linePoint = parseInt(maxPoints / arr.length)
const obj = arr.find(obj => obj.name == newObj.paramName);
if (obj) {
obj.addPoint({ x: newObj.time, y: parseFloat(newObj.currentVal), marker: { enabled: true } });
// 检查当前数据点数量并移除最早的数据点
if (obj.data.length > linePoint) {
obj.data[0].remove(); // 删除第一个数据点
}
}
},
现在情况就是,我在看了折线图之后,我将浏览器后台运行,减小之后,我去写文档或者看视频等别的操作。等过一会再打开浏览器,就直接卡死。
要求是,浏览器后台之后,持续运行当前界面,不停的刷新,与ws推送保持一致。
有两种情况第一种是打开之后,直接卡死,表格与统计图均不会更新。
第二种情况是打开之后,表格上有时间展示,时间会从浏览器切换到后台运行的时间,持续连跳到目前时间,(原本应该是 1,2,3,4,5,时间间隔为1秒,现在变成1,3,5这种,时间间隔远低于1s,客户描述,开发未复现)
将浏览器设置 始终让这些网站保持活动状态添加之后还是会有卡死情况出现。如何解决这个问题。
求大佬给一种解决思路
百度得到的结果是ws切换后台之后是会持续运行的,并不会受到浏览器后台的影响
用
SharedWorker
,在里面连接webSocket
,这样即便页面在后台,也可以正常接收数据。Chrome 浏览器开发者工具可以抓内存快照,帮助分析卡死的问题。
不过,或许可以换个更新思路——
webSocket
不用来推送数据,而是推送通知,后端推一个很小的数据,告诉前端有更新了,前端收到就调 http 去拉取数据。如果换成 SSE 推送这种通知的话,服务器的开销就更小了。
代价就是需要后端跟着改。