4***@qq.com
4***@qq.com
  • 发布:2020-12-24 08:53
  • 更新:2021-06-30 17:27
  • 阅读:8423

uniapp 调用echarts 占用内存过大不释放问题终于解决了 移动端支持echarts 5.0

分类:uni-app

uniapp 调用echarts 这个问题整了四天终于过了
总结下经验:
最开始做图表本来想用以前flutter上那款,结果没发现vue版本,最后退而求其次选echarts,什么uchart这些根本就没入法眼,界面没得echarts好看二个功能上没得这个强,那就开干

  1. 最开始信了官方的鬼话用renderjs,说性能有多强大,调是调了,也显出来了,最后发现一个重大问题,renderjs操作dom元素会不释放内存,就算调了disponse方法也没用,只把实例给剁了,加载到页面上的那个js文件还在内存中没得到释放,这个东东起码搞了我两天,最后放弃renderjs

  2. 下来又找,最后发现mpvue-echarts 这个东东试了还可以,内存也能及时回收,速度也够快, 不过这个东东停止维护了,示例上边的echarts.js文件有点老还是个simple的阉割版,样式没有5.0好看,官方下了个5.0上来,一来就报一堆错,以为不兼容新版,又找结果还真有改进版的,拿上去还是不对,版本从3.7一直下到5.0全试了一个遍,还是没对,晚上下搞到早上8点过才搞通,最后才发现原来echarts官方那个在线定制功能惹的祸,那个编译出来的包拿这上边根本过不了.最后下了个5.0整个项目包,dist目录下的文件拿过来一试就OK.

苹果7真机上边app测试完美通过,
H5上边报错 需要把echarts的js文件中 两处操作dom元素的
addEventListener语句删除
因为这个不是直接操作dom元素而是cavnas画板渲染,不需要这两处监听

两处分别为:
&& !!window.addEventListener
el.addEventListener(name, handler, opt); 压缩版 t.addEventListener(n,e,i)改为null

基本操作就是:
https://github.com/dcloudio/hello-uniapp/blob/master/components/mpvue-echarts/src/echarts.vue 上边拿 mpvue-echarts 目录下src下边两个文件
echarts.vue 要做点小修改:
删除error事件
删除mounted 和 onReady 的H5条件编译 不然手机显示白屏

上代码:

<template>  
    <view class="content">  
        <mpvue-echarts class="ec-canvas"   
    @onInit="lineInit" canvasId="line" ref="lineChart" />  
    </view>  
</template>  
<script>  
import * as echarts from '../../components/mpvue-echarts/echarts.min.js';   //官方下载的5.0库  
import mpvueEcharts from '../../components/mpvue-echarts/echarts.vue';  
//-------------------------------------------------------------  
 //官方演示option,这个地方方便从官方上拷示例把 let隔了一行  
let   

option = {  
    title: {  
        text: '某地区蒸发量和降水量',  
        subtext: '纯属虚构'  
    },  
    tooltip: {  
        trigger: 'axis'  
    },  
    legend: {  
        data: ['蒸发量', '降水量']  
    },  
    toolbox: {  
        show: true,  
        feature: {  
            dataView: {show: true, readOnly: false},  
            magicType: {show: true, type: ['line', 'bar']},  
            restore: {show: true},  
            saveAsImage: {show: true}  
        }  
    },  
    calculable: true,  
    xAxis: [  
        {  
            type: 'category',  
            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']  
        }  
    ],  
    yAxis: [  
        {  
            type: 'value'  
        }  
    ],  
    series: [  
        {  
            name: '蒸发量',  
            type: 'bar',  
            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],  
            markPoint: {  
                data: [  
                    {type: 'max', name: '最大值'},  
                    {type: 'min', name: '最小值'}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        },  
        {  
            name: '降水量',  
            type: 'bar',  
            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],  
            markPoint: {  
                data: [  
                    {name: '年最高', value: 182.2, xAxis: 7, yAxis: 183},  
                    {name: '年最低', value: 2.3, xAxis: 11, yAxis: 3}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        }  
    ]  
};  

//------------------------------------------  

export default {  
    //导入mpvue的mpvueEcharts组件。  
    components: {  
        mpvueEcharts  
    },  
    data() {  
        return {};  
    },  
    onLoad() {},  
    methods: {  
        lineInit(e) {  
            let { width, height } = e;  
            let canvas = this.$refs.lineChart.canvas;  
            echarts.setCanvasCreator(() => canvas);  
                        //这步很关键能拿到对象就万事大吉  
            let lineChart = echarts.init(canvas, null, {  
                width: width,  
                height: height  
            });  
            canvas.setChart(lineChart);  
            lineChart.setOption(option);  
            this.$refs.lineChart.setChart(lineChart);  
        }  
    }  
};  
</script>  

<style>  
//容器必须设高度宽度否则无法显示  
.content {  
    height: 1200rpx;  
    width: 100%;  
}  
//画板宽高  
.ec-canvas{  
    height: 1200rpx;  
    width: 100%;  
}  
</style>
2 关注 分享
九涯 damdmen

要回复文章请先登录注册

s***@qq.com

s***@qq.com

https://github.com/dcloudio/hello-uniapp/blob/master/components/mpvue-echarts/src/echarts.vue的文件好像跟你的有点不一样,没有onInit,不知道楼主你的是什么版本
2021-06-30 17:27
易软

易软

报 js堆内存不足
2021-04-09 11:14
易软

易软

平板上不行吗?我在小米平板上怎么弄就是不显示
2021-04-09 11:11
m***@163.com

m***@163.com

因为我的echarts是npm安装的,所以修改echarts有点麻烦,所以看了一下echarts源码之后,觉得既然只是addEventListener无法调用,也似乎不需要调用,那我就给它一个空白函数就好了,省的去改echarts源码那么麻烦

```javascript
initChart(e) {
const { width, height } = e;
const canvas = this.$refs.chart.canvas;

// 此处直接给canvas加了一个空白的addEventListener
canvas.addEventListener = () => {};

echarts.setCanvasCreator(() => canvas);
this._chart = echarts.init(canvas, null, {
width,
height
});

canvas.setChart(this._chart);
this._chart.setOption(this.chartOption);
this.$refs.chart.setChart(this._chart);
}
```
2021-01-19 17:24
[已删除]

[已删除]

承接H5、小程序、APP等外包:
1. 经验丰富,做过多种类型项目,有案例可看;
2. 整个项目外包可以找我(小团队接单,面向客户、产品);
3. 只需要前端部分也可以找我(个人接单,面向服务端合作伙伴);
4. wechat(13070273424);
2021-01-10 13:29
4***@qq.com

4***@qq.com (作者)

回复 1***@qq.com :
我在烂苹果7上边试非常流畅,比renderjs好太多.
2021-01-09 20:57
1***@qq.com

1***@qq.com

楼主,这种情况下,配置animationDelay等属性是可以了,但是整体动画会有点卡卡的,不知道您有没有遇到过呢
2021-01-08 12:13
4***@qq.com

4***@qq.com (作者)

回复 1***@qq.com :
动态获取你只需要把lineChart 保存出来,更新只需要更新series中间的数组就可以了,然后用你保存出来的linechart set一下option就可以了
2021-01-02 22:00
4***@qq.com

4***@qq.com (作者)

回复 1***@qq.com :
最新的5.0都可以
2021-01-02 21:57
1***@qq.com

1***@qq.com

楼主这个方法可以使用echarts其他版本么?
我原来用mpvue-echart发现可以显示图表,但是动态获取图表数据的时候,图表渲染的很慢请问陋之知道这个是怎么回事么?
2020-12-30 17:33