记一次微信小程序echarts体积太大的优化过程

5,081 阅读2分钟

我正在参与掘金创作者训练营第4期(带链接:juejin.cn/post/706419…

在小程序中使用echarts

首先下载echarts组件
Release v2.0.0 · ecomfe/echarts-for-weixin (github.com)

在app.json中加入以下语句

{
  "usingComponents": {
    "ec-canvas": "../../ec-canvas/ec-canvas"
  }
}

配置完成后 我们就可以在wxml当中使用 ec-canvas 组件

  <ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>

尝试优化体积

  1. 通过自定义构建 缩小echarts的体积
    echarts.apache.org/builder.htm…

这里只勾选需要的图表和功能
echarts.min.js 大概有950.54k,自定义构建后大小为689k image.png image.png

  1. 使用分包减轻主包体积压力

目前小程序分包大小有以下限制:

  • 整个小程序所有分包大小不超过 20M
  • 单个分包/主包大小不能超过 2M

因为现有的项目组件库 + echarts就已经达到1.8M左右,所以考虑过使用分包,将echarts分散到各个分包中,这样也能大概支持10多个分包,最终才会达到20M的限制。但考虑到现有项目规模后续还会扩大的原因,也在网上参考了其他人的解决方案,最终还是选用了we-script

利用we-script 外置echarts

安装

首先要删除ec-canvas文件夹下的echarts.js
然后安装we-script

npm install --save we-script

在app.json里添加

{
  "usingComponents": {
    "we-script": "we-script"
  }
}

让ec-canvas支持远程引用echarts

ec-canvas/ec-canvas.wxml

<!-- 远程引入echarts -->
<we-script
  src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts/5.0.2/echarts.min.js"
  bind:onLoad="echartsLoad"
/>
<!-- 新的:接口对其了H5 -->
<canvas wx:if="{{isUseNewCanvas}}" type="2d" class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas>
<!-- 旧的 -->
<canvas wx:else class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas>

ec-canvas/ec-canvas.js

// import * as echarts from './echarts'; 注释本地引入echarts的语句
let echarts = null

Page({
    ...
    methods: { // methods加入这个方法
        async getEcharts(e) {
          echarts = e.detail.context.echarts;
        },
    }
})

使用

index.wxml

<we-script
    src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/echarts/5.0.2/echarts.min.js"
    bind:onLoad="echartsLoad"
>
<view class="container">
  <ec-canvas
      wx:if="{{ echarts }}"
      id="mychart-dom-bar"
      canvas-id="mychart-bar"
      ec="{{ ec }}">
      echarts="{{ echarts }}"
  </ec-canvas>
</view>

index.js
ps: 如果是通过 npm install echarts-for-weixin 方式使用echart, 需要手动传入echarts 设置echarts属性为 echarts="{{ echarts }}" ( 个人真机测试过,如果用这种方式 会因为setData数据长度过长,导致小程序卡死30秒 )
而下载下来的ec-canvas, 它会默认引入同文件夹下的echart.js, 而且无法传入echarts

Page({
  data: {
    echarts: null,
    ec: {
      onInit: (canvas, width, height, dpr) {
        const chart = echarts.init(canvas, null, {
          width: width,
          height: height,
          devicePixelRatio: dpr
        });
        canvas.setChart(chart);

        var option = {
          ...
        };
        chart.setOption(option);
        return chart;
      }
    }
  },
  echartsLoad(e: any) {
    const echarts = e.detail.context.echarts
    this.setData({
        echarts: echarts
    })
  }
});

结果

f2e57204ba4b82fb701def36d5c344f.jpg

最后

暂时使用了一段时间,微信官方好像并没有对这种eval代替库进行封禁或者屏蔽
由于本人水平有限,如有不对的地方,请各位指正。

相关网址:
eval5 - 基于JavaScript编写的JavaScript解释器 - 知乎 (zhihu.com)
用 JavaScript 写成的 JavaScript 解释器,意义是什么? - 知乎 (zhihu.com)