基于vue-cli的轮播性能优化

603 阅读2分钟

背景介绍

模块功能为长期挂载,其中有一块内容需要轮播展示,轮播(轮播使用的element-UI)中存在不同的图。(比如:一张图里面有线图、饼图、柱状图;第二章图里面可能就只有几个线图。)轮播时间为10s一次,所以页面展示数据也是10s更新一次。

初始代码引起的性能问题

  1. 挂载10张图一起轮播,就算保留三个图数据,其他使用空状态,也只能是挂载10个小时左右
  2. 使用v-if造成的VNode没有清除

问题定位

谷歌调试工具,发现vnode一直会增加。同时window也在增加,怀疑形成了闭包

尝试解决办法

  1. 尝试去掉页面数据引用。比如XXX.contrcutor === 'Object' || XXX.contrcutor === 'Array'
  2. 去掉echart图的 window.addEventListener监听事件,window.removeEventListener,原因是会形成闭包
  3. echart图每次数据更新时使用,都是用echart.clear()
  4. 将轮播数据只保留三个,也就是说三张轮播图

结果:内存虽然有所降低,但是依然存在内存不断的堆积。无法释放,依然不能达到长期挂载的要求

再次使用谷歌工具跟踪性能

依然发现我们vnode增加。
这时查看了关于Virtual Dom的相关知识,v-if其实在内存之中不显示的节点依然保留了他们的相关虚拟dom并没有销毁。

尝试修改第二弹

  1. 将页面上面的v-if修改样式控制visibility控制,发现存在内存依然没有清除情况,vnode依然持续增加
  2. 将页面中的echart图都去除,发现每次残留的内存有多降低。
  3. 将页面上面只保留echart图,其他样式先隐藏,--结果,内存增加幅度比较大。怀疑是echart图的内存没有清除
  4. 清理echart图的实例。clear()只能清空当前实例,会移除实例中所有的组件和图表,清空后调用 getOption 方法返回一个{}空对象。但是dispose()销毁实例,销毁后实例无法再被使用。

所以我采用了dispose方法。在结合vue组件的生命周期钩子,在父组件里面定时给轮播组价v-if一次,可以清除掉其他内容存在的内存堆积。完美解决