【前端-优化】vue项目构建以及打包优化,多手段,含对比

237 阅读3分钟

一、背景

  1. 项目过大,启动需要接近6分钟

image.png 2. 热更新时间编译时间过长

image.png

二、分析

分析主要采取2种手段

1、speed-measure-webpack-plugin 插件,它可以帮助你分析和测量 Webpack 构建过程中的每个阶段所花费的时间。通过使用该插件,你可以深入了解 Webpack 执行构建任务的性能瓶颈,并优化你的构建配置,使得构建速度更快、更高效。

首先安装speed-measure-webpack-plugin

yarn add -D speed-measure-webpack-plugin

vue.config.js主要代码:

     const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
     configureWebpack: config => {
         config.plugins.push(new SpeedMeasurePlugin())
     }

使用之后,会有一些分析信息,长这样:

image.png 这里面主要是一些任务消耗时间,可以明显的看出,主要是loader消耗,此外,终端有着大量的eslint的警告信息,看路径,是node_modules下面的文件

image.png

2、 打包文件分析。vue-cli 有内置命令,package.json 配置

 "report": "vue-cli-service build --report" 

此时运行

npm run report

输出目录会得到report.html

image.png

浏览器打开这个文件

image.png

里面列出了打包生成的代码块,接下来我们着手开始优化

三、优化

1、针对eslint的警告,可以发现,eslint去检测了node_modules,这是不必要的,所以我们去.eslintignore文件,配置node_modules的检测忽略

/node_modules

此时重新启动项目

image.png 发现编译时间已经缩减至2分11秒

2、 编译过程的优化,编译过程主要费时间的任务,其实主要是两点:

  • 解析文件,less、vue、 postcss等的loader,由于文件数量太多,导致任务时间过长
  • 生成文件

一般对于这种情况,都是采用缓存+多进程优化,我们首先开启缓存,主要利用hard-source-webpack-plugin 首先安装

yarn add -D hard-source-webpack-plugin

vue.config.js 配置

configureWebpack: config => {
  
  config.plugins.push(new HardSourceWebpackPlugin({
    // Either an absolute path or relative to webpack's options.context.
    cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
    // Either a string of object hash function given a webpack config.
    configHash: function(webpackConfig) {
      // node-object-hash on npm can be used to build this.
      return require('node-object-hash')({sort: false}).hash(webpackConfig);
    },
    // Either false, a string, an object, or a project hashing function.
    environmentHash: {
      root: process.cwd(),
      directories: [],
      files: ['package-lock.json', 'yarn.lock'],
    },
    // An object.
    info: {
      // 'none' or 'test'.
      mode: 'none',
      // 'debug', 'log', 'info', 'warn', or 'error'.
      level: 'debug',
    },
    // Clean up large, old caches automatically.
    cachePrune: {
      // Caches younger than `maxAge` are not considered for deletion. They must
      // be at least this (default: 2 days) old in milliseconds.
      maxAge: 2 * 24 * 60 * 60 * 1000,
      // All caches together must be larger than `sizeThreshold` before any
      // caches will be deleted. Together they must be at least this
      // (default: 50 MB) big in bytes.
      sizeThreshold: 50 * 1024 * 1024
    },
  }))
},

具体配置大家可以 去官网查阅

此时再重新启动项目(注意:第一此启动不会有时间变化,第二次才会启用缓存)

image.png

可以发现,此时只需要1分40秒

另外,其实也可以启动webpack自带的缓存

module.exports = {
//...
cache: false,
};

此项配置没有hard-source-webpack-plugin速度快,稳定性也不如,但是不用下载额外插件

3、开启多进程加速构建

根据webpage 官方示例配置,thread-loader必须放在use的首位,由于vue-cli创建的项目不会得到完整的配置,我们可以采用一条指令得到完整的配置项,packapge.json增加:

        "inspect": "vue-cli-service inspect > inspect.js"

项目根目录会得到inspect.js,这里是完整的配置文件,找到 test: /.m?jsx?$/,可以看到首位的use,我这里已经配置好了thread-loader,所以会在首位,相同的道理找到vue-loader的use,大家根据实际情况修改vue.config.js

image.png

vue.config.js 增加配置:

// cpu核数
const threads = os.cpus().length
const threadLoader = require('thread-loader')
chainWebpack: (config) => {
 config.module
      .rule('js')
      .use()
      .loader('thread-loader')
      .before('babel-loader')
      .options({
        workers: threads
      })
      .end()
}
config.module
      .rule('vue')
      .use()
      .loader('thread-loader')
      .before('cache-loader')
      .options({
        workers: threads
      })
      .end()

至此,多进程配置完成。大家更具实际情况配置,不要照抄,我关闭了缓存,我们来看下构建加速效果

image.png 效果不大,还不如缓存实在,优化失败了,优化的过程中,有一个过程花费了大量的时间

image.png 热更新过程中的时间是这样的,说明cache-loader,vue-loader并没花费多少时间

image.png

很明显,emitting HtmlWebpackPlugin这一步有很明显的问题,这一步主要是更新html,我们打开dev-tools

image.png

基本可以确定,是懒加载组件太多,导致emitting HtmlWebpackPlugin花费了大量的时间,接下来,我们优化开发环境的懒加载组件,由于我们是一个后台管理系统,动态获取的路由,并且页面全部都是懒加载,找到关件代码改造

4、开发环境懒加载优化

image.png

修改为:

component:
        process.env.NODE_ENV === 'production'
          ? () =>
              import(/* webpackChunkName: "component" */ `@/${component}.vue`)
          : () => {
              try {
                return Promise.resolve(
                  require('@/' + component + '.vue').default
                )
              } catch (err) {
                console.log(err)
              }
            },

效果显著:

image.png

接下来,咱们把所有的优化全部打开,这是第一次打开,缓存未使用的时间:

image.png 热更新时间:

image.png 接下来,重新启动项目:

image.png

热更新:

image.png

结语

此时的时间已经属于能接受的范围内,优化效果也比较明显,起主要作用的手段还是缓存跟懒加载变固定路由,多进程有一定效果,但不是决定性的,据了解,需要看项目的大小,越大,越多的文件,越有效果,下次有时间,试试dll提取公共库之后的优化效果,并对比这些手段的效果