吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 196|回复: 1
上一主题 下一主题
收起左侧

[会员申请] 申请会员ID: Resthx

[复制链接]
跳转到指定楼层
楼主
吾爱游客  发表于 2024-11-15 11:02 回帖奖励 |自己
1、申 请 I D:Resthx
2、个人邮箱:905459569@qq.com
3、原创技术文章:记录一次echarts图表大数据量轮询刷新页面卡死问题的优化
原创文章连接https://blog.csdn.net/qq_3527080 ... 1001.2014.3001.5502
全栈开发者,擅长java,rust,javascript等语言,linux系统运维,容器化,集群等,个人博客名字:爱音乐的程序猿,链接:https://blog.csdn.net/qq_35270805
目前已有70多篇个人原创文章,总共24w阅读量

记录一次echarts图表大数据量轮询刷新页面卡死问题的优化

项目场景:

在我们的项目架构中,集成的Echarts图表组件采用了折线图,业务需求即每300毫秒自动更新图表上的数据,并且每一次的数据点数量达到了约700个,折线图刷新的很快,每300毫秒就要刷新数据

问题描述

开发过程中发现在这种数据量请求频率下,大概2个小时左右就会导致整个页面卡死,无法操作。问题很严重

原因分析:

经过详细的排查发现是echarts图表在大数据量下确实会有这种问题。我们业务虽然只有两个图标,但更新频率很快,也遇到了此问题。原因是多方面的,一个是配置不高的电脑cpu撑不住,一个echarts也有内存问题,在大数据量频繁刷新内存和cpu撑不住,直接导致页面崩溃。经过考虑采取先不降低频率,先优化图表方式。解决这个问题需要从多方面下手

解决方案:

1.解决定时轮询稳定性:将定时轮询单独放在一个线程中,稳定定时任务运行效率参考代码:

// worker.js   self.addEventListener("message", function (event) {  const { task } = event.data;  console.log("worker", task);  if (task === "getChartData") {          //创建定时任务    if (!self.timerThread) {      self.timerThread = this.setInterval(async () => {        self.postMessage({});      }, 300);    }  }else if (task === "stop") {    //清除定时任务    if (self.timerThread) {      this.clearInterval(self.timerThread);      self.timerThread = undefined;    }  }});

调用

    stopComputation(){      if (this.worker != null) {        this.worker.postMessage({ task: 'stop'});        this.worker.terminate();        this.worker = null;      }    },        startTimer(){      if (this.worker != null) {        this.stopComputation()      }      this.worker = new Worker(new URL('./chartthread.js', import.meta.url));      this.worker.postMessage({ task: 'getChartData'});      this.worker.onmessage = async () => {        console.log('Worker has been getVibration...............................');        this.getVibration()      };      // 清理 Worker      this.worker.onclose = function() {        console.log('Worker has been terminated.');      };

修改之后发现发现有效果,但是效果不明显,最后还是卡死

2.将echarts实例单独提取到vue外部,避免vue多余监听浪费性能具体代码

<script>import elementResizeDetectorMaker from 'element-resize-detector' // 尺寸监听组件//设置此处会被多个vue组件公用,所以用key,value方式保存各个组件页面的实例,避免echarts实例公用let echartObject = {}export default {         .......此处省略部分代码........  data () {    return {      options: {},      chartInstanceIndex: null, //图表实例      timer: null    }  },  mounted () {    //随机8位数    this.chartInstanceIndex = Math.random().toString(36)    this.timer = setInterval(() => {      this.initChart()    }, 60000)    this.initChart()    const erd = elementResizeDetectorMaker()      // 为了健壮性,可以考虑一下这里获取dom元素进行一个判断,如果没有获取到dom元素就不进行监听,这里就这样了      erd.listenTo(document.getElementById(this.id), (element)=> {        if (echartObject[this.chartInstanceIndex != null && echartObject[this.chartInstanceIndex != undefined) {          echartObject[this.chartInstanceIndex.resize()        }      })  },  methods: {    initChart() {      if(!document.getElementById(this.id)){        return      }       if (echartObject[this.chartInstanceIndex != null && echartObject[this.chartInstanceIndex != undefined) {        echartObject[this.chartInstanceIndex.dispose()        echartObject[this.chartInstanceIndex == null      }      echartObject[this.chartInstanceIndex = this.$echarts.init(document.getElementById(this.id))      this.options = {...省略....}      echartObject[this.chartInstanceIndex.setOption(this.options)    },    updateData () {      if(echartObject[this.chartInstanceIndex != null){        echartObject[this.chartInstanceIndex.setOption({          series: [{            data: this.yData          },        })      }    }  }}</script>

3.关闭动画可提高性能

官网配置项
options.animation改成false

4.配置折线图在数据量远大于像素点时候的降采样策略

官方文档:官方文档

有几种采样算法,此处我才用了第一种lttb算法。经过前面几个方法优化效果明显,但经过大约4个小时后还是撑不住,最终使用了下面的方法成功解决问题

5.定时删除并重新创建echarts实例

如果试了上面的方法还是不行。那么最后一种方式可以试一下。原理是定时重新创建并清除旧的实例,相当于重新初始化一次
代码参考:

<script>import elementResizeDetectorMaker from 'element-resize-detector' // 尺寸监听组件let echartObject = {}export default {  ...............................  data () {    return {      options: {},      chartInstanceIndex: null, //图表实例      timer: null    }  },  destroyed() {    if (this.timer!=null) {      clearInterval(this.timer)      this.timer == null    }  },  mounted () {    //随机8位数    this.chartInstanceIndex = Math.random().toString(36)    this.timer = setInterval(() => {            //定时重新初始化      this.initChart()    }, 60000)    this.initChart()...........................  },  ..............  methods: {    initChart() {      if(!document.getElementById(this.id)){        return      }       if (echartObject[this.chartInstanceIndex != null && echartObject[this.chartInstanceIndex != undefined) {        echartObject[this.chartInstanceIndex.dispose()        echartObject[this.chartInstanceIndex == null      }      echartObject[this.chartInstanceIndex = this.$echarts.init(document.getElementById(this.id))      this.options = {........................}      echartObject[this.chartInstanceIndex.setOption(this.options)    },    updateData () {      if(echartObject[this.chartInstanceIndex != null){        echartObject[this.chartInstanceIndex.setOption({          series: [{            data: this.yData          },        })      }    }  }}</script>

经过该方式优化后成功解决了长时间运行页面卡死的问题

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
Hmily 发表于 2024-11-15 13:56
抱歉,未能达到申请要求,申请不通过,可以关注论坛官方微信(吾爱破解论坛),等待开放注册通知。

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-23 22:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表