VUE2 WebSocket在浏览器后台时数据堆积卡顿问题如何解决?

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切换后台之后是会持续运行的,并不会受到浏览器后台的影响

阅读 1k
2 个回答

SharedWorker,在里面连接 webSocket,这样即便页面在后台,也可以正常接收数据。

Chrome 浏览器开发者工具可以抓内存快照,帮助分析卡死的问题。

不过,或许可以换个更新思路——webSocket不用来推送数据,而是推送通知,后端推一个很小的数据,告诉前端有更新了,前端收到就调 http 去拉取数据。
如果换成 SSE 推送这种通知的话,服务器的开销就更小了。
代价就是需要后端跟着改。

为什么切换tab之后还要继续运行代码,这样对客户端来说也不太友好,浏览器之所以切换后就暂停一些代码的运行,是出于性能优化。那我们遵循它不就好了。监听页面是否在激活状态,激活状态才去接收后端推送的数据,失活状态就不接收,不是更好吗?

监听是否激活状态:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/vis...

$(document).on('visibilitychange', function () {
        if (document.hidden === true) {
            // 页面被挂起
            console.log("页面挂起:", connection_DB)
        } else {
            // 页面由挂起被激活
            console.log("页面由挂起被激活", connection_DB)
           
        }
    })
推荐问题
宣传栏