Echarts 如何防止内存泄漏

@

概述

在使用Echarts时是很容易产生内存泄漏的,产生内存泄漏的原因是实例化echarts报表后在销毁组件前没有对echarts的实例进行删除。

代码

// 此段代码建议写在mixin中,在使用echarts时调用即可
beforeDestroy() {
    if (!this.chart) {
        return
    }
    // 在组件销毁前调用dispose函数销毁报表
    this.chart.dispose()
    this.chart = null
}

完整代码

此代码直接使用mixin混入即可,封装了报表自适应和报表销毁功能,在每一个报表组件中引入就好。

import { debounce } from '@/utils/common'

export default {
  data() {
    return {
      $_sidebarElm: null,
      chart: null,
      dataEmpty: false,
    }
  },
  watch: {
    data(newVal) {
      if (!this.chart) {
        this.$_init();
      } else {
        this.setData(newVal);
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.$_init();
    });
    this.$_initResizeEvent()
  },
  beforeDestroy() {
    this.$_disposeChart()
    this.$_destroyResizeEvent()
  },
  activated() {
    this.$_initResizeEvent()
  },
  deactivated() {
    this.$_destroyResizeEvent()
  },
  methods: {
    /**
     * 初始化数据
     */
    $_init() {
      if (this.data && this.data.length === 0) {
        this.dataEmpty = true;
      } else {
        this.dataEmpty = false;
        this.initChart();
        this.setData(this.data);
      }
    },
    $_resizeHandler() {
      return debounce(() => {
        if (this.chart) {
          this.chart.resize()
        }
      }, 100)()
    },
    $_initResizeEvent() {
      window.addEventListener('resize', this.$_resizeHandler)
    },
    $_destroyResizeEvent() {
      window.removeEventListener('resize', this.$_resizeHandler)
    },
    // 销毁报表
    $_disposeChart() {
      if (!this.chart) {
        return
      }
      this.chart.dispose()
      this.chart = null
    }
  }
}

debounce函数

/**
 * 防抖函数
 * @param {Funciton} fn 函数
 * @param {Number} wait 等待时间
 * @param {immediate} Boolearn 是否立即执行
 */
export function debounce(fn, wait, immediate) {
  let timer
  return function() {
    if (timer) clearTimeout(timer)
    if (immediate) {
      // 如果已经执行过,不再执行
      var callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, wait)
      if (callNow) {
        fn.apply(this, arguments)
      }
    } else {
      timer = setTimeout(() => {
        fn.apply(this, arguments)
      }, wait)
    }
  }
}
posted @ 2023-04-26 20:53  爱吃土豆丝嗯  阅读(186)  评论(0编辑  收藏  举报