数据可视化大屏设计器开发-umi打包体积优化

532 阅读5分钟

数据可视化大屏设计器开发-umi打包体积优化

开头

本文是数据可视化开始的开发细节第四章。关于项目打包体积优化。
虽然内容似乎不应该按这个顺序产出,不过因为最近的迭代中突然有涉及到这个方面,故就趁这个时机赶紧先记下来。

简单说明
本人只是一个菜鸡,所以并没有什么新的东西,只是把网上碰到的一些点给统一整理了下。

开始

大屏是基于umi进行开发的,关于此库相信大家都不陌生,只需很少的配置即可开始研发。

但是随着时间的推移,项目的代码量越来越大,打包出来的产物也越来越大,这个时候便需要做一些优化配置。

体积优化是在开发1.17版本的时候,首先是上一个版本的打包详情。

之前的版本打包.jpg

首页加载之前.jpg

然后是当前优化后的打包详情。

现在的版本打包.jpg

首页加载之后.jpg

本文说得更明白些,应该说是主文件的体积优化,整体的思路:拆分主文件、按需加载、压缩。

umi配置优化

dynamicImport

正常情况下,umi打包只会生成一个umi.js,简单项目这样也很简洁,但是项目大的时候,网络加载速度就会变慢,此时就需要按照逻辑进行拆分。
可以看下官网的按需加载,开启按需加载后,umi就会将项目按模块进行拆分。

targets

根据实际情况,针对项目应用的浏览器版本范围,按需引入polyfill,可以很好的减少产出代码体积。
如果项目只会应用于高版本的浏览器,就可以设置成高版本浏览器的配置,减少polyfill

externals

即是webpackexternals,把一些模块从打包项中直接给去除掉,采用cdn的形式引入。

  • ps
    本来是准备打算将echarts采用cdn形式引入的,奈何还依赖了词云水球组件,删除了echartsnpm后,报错了,故没有做这个选择。

ignoreMomentLocale

大多数情况下,业务项目基本都没有多语言的需求,把moment的语言包给去除。

当然更好的办法是把moment替换成dayjs,毕竟其实平时没有太多时间转换的需求,采用更轻量的库是更好的选择。

splitChunks

根据上面的dynamicImport拆分了模块后,模块当中的第三方引入却被同时打进了不同的模块中,重复打包。

使用webpacksplitChunks配置,将一些比较大的,常用的第三方依赖单独抽离,可以有效减少包体积。

{
  chunks: ['antdesigns', 'vendors', 'commons', 'umi'],
  chainWebpack(config: any) {
    config.merge({
      optimization: {
        minimize: true,
        splitChunks: {
          chunks: 'all',
          minSize: 30000,
          minChunks: 1,
          automaticNameDelimiter: '.',
          cacheGroups: {
            antdesigns: {
              name: 'antdesigns',
              chunks: 'all',
              test: /[\\/]node_modules[\\/](antd|@ant-design)/,
              priority: 10,
            },
            echarts: {
              name: 'echarts',
              chunks: 'async',
              test: /[\\/]node_modules[\\/](echarts|zrender)/,
              priority: 10,
            },
            vendors: {
              name: 'vendors',
              chunks: 'all',
              test: /[\\/]node_modules[\\/](lodash|moment|react|dva)/,
              priority: 10,
            },
            commons: {
              name: 'commons',
              // 其余同步加载包
              chunks: 'all',
              minChunks: 2,
              priority: 1,
              enforce: true,
            },
          },
        },
      });
    }
  },
}
注意的地方

splitChunks中还有几个需要注意的地方。

  • priority
    拆分的优先级,当一个包同时被多个cacheGroups中的test匹配上时,会将包priority最高的那个cacheGroups中。
  • minSize
    包被压缩前的体积超过minSize才会被拆包。
  • chunks(个人理解)
    umi配置中的chunks,表示预先需要加载的cacheGroups,比如上面的echarts模块不需要一开始就加载,则不需要添加到chunks中。

按需加载

这里说的按需加载,说的是代码的按需加载。
比如在加载首页的时候,我们不需要加载个人中心的页面代码,这样可以大大加快首页加载的速度。

此时就可以用到React的语法来达到这个效果(其实完全可以使用umidynamic,但是不不知道为啥报错了)。

import React, { lazy, Suspense } from 'react'

// 一个比较大的组件
const HugeComponent = lazy(() => {
  return import(/* webpackChunkName: "Chunk_Name" */ './path/to/component')
})

const App = () => {

  return (
    <Suspense fallback={<div>loading...</div>}>
      <HugeComponent />
    </Suspense>
  )

}

按需加载组件,只有使用到组件的时候才进行加载,lazy支持一个异步函数,返回一个组件,Suspense组件的children为一些懒加载的组件,在未加载完成时,会显示fallback的加载内容。

大屏设计器当中有非常多的依赖,且体积巨大,通过此方法,实现了一个非常不错的效果。
比如经常使用的代码编辑器monaco-editor
还有每一个图表组件,默认都不进行加载,只有当拖拽到画布当中时,才会真正去加载图表。

其他优化

gzip

之前的优化效果虽然显著,但是当开启了gzip之后,给项目最后的效果来了一个质的提升。

这是压缩前和压缩后的两个对比,效果非常明显。

gzip前.jpg

gzip后.jpg

  1. 依赖
    yarn add compression-webpack-plugin@5.0.1 -D
    为什么安装这个版本
    项目使用的是umi3,而插件的最新版本是10.0.0,打包发现报错Cannot read properties of undefined (reading ‘tapPromise‘)
    大概率是webpack版本不匹配,查看插件package.json发现其依赖的webpack版本为5
    故选择了插件5.0.1版本(webpack可为4)。

  2. 配置

  import CompressionPlugin from 'compression-webpack-plugin';
  const config = {
    chainWebpack(config: any) {
      // 生产环境配置
      if (REACT_APP_ENV === 'prod') {
        config.plugin('compression-webpack-plugin').use(CompressionPlugin, [
          {
            test: /\.(js|css|html)$/i, // 匹配
            threshold: 102400, // 超过10k的文件压缩
            deleteOriginalAssets: false, // 不删除源文件
          },
        ]);
      }
    },
  }
  1. nginx配置
    当然只完成打包还不够,需要服务端也支持gzip
    只需要简单的在nginx配置当中添加如下配置,重启,即可。
  gzip_static on;

剩余待优化

组件优化

现在各个图表组件的配置渲染已完成按需加载,但是每个组件的默认配置数据仍然是同步全量加载。
因为代码逻辑原因可能需要一番大修改,故在之后完善。

图片优化

图片现在也是全量加载,待优化。

依赖包替换

有相当多的依赖包只是简单使用,但占用体积巨大,考虑使用同功能的小包进行替换。

结束

结束🔚。

顺便在下面附上相关的链接。

试用地址
试用账号
操作文档
代码地址

参考链接

juejin.cn/post/708145…
blog.csdn.net/moozixiao/a…
juejin.cn/post/710383…
juejin.cn/post/715565…
juejin.cn/post/684490…
juejin.cn/post/684490…