vue-cli项目打包优化

vue-cli项目打包优化

背景

随着不断增加的业务代码,项目越来越大,咱家的webpack反应速度也越来越慢,有时候还出现假死现象,这已经到了不能容忍的地步了, 打工人搬砖已经很累了,求求你不要这么慢了

1、准备工作:检测webpack优化的plugin

我们要优化webpack打包,首先得了解我们的bundle文件,分析每个模块的大小,分析打包时间主要位于哪里,这里我们主使用两个webpack的plugin,

js 复制代码
# Yarn 
yarn add -D speed-measure-webpack-plugin 
yarn add -D webpack-bundle-analyzer

vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
module.exports = {
    // ...省略
    configureWebpack: {
         plugins: [
          new SpeedMeasurePlugin(),
          new BundleAnalyzerPlugin()
    ],
    ...
}

1.1 配置speed-measure-webpack-plugin

从下图面的输出结果中,很容易看到对应的耗时模块.

1.1 配置speed-measure-webpack-plugin

speed-measure-webpack-plugin,则主要是展示打包后的模块信息

从图中,可以清晰的看出打包的各个模块的速度与体积,以便于后续的优化展示

2.优化开始

首先我们对build:test进行配置,方便后续调试,如果项目下没有vue-config.js,自己需要新建一个

js 复制代码
 "scripts": {
    // ...
    "build:test": "vue-cli-service build --mode test --report"
  },

2.1 thread-loader ------ 开启多线程优化

在vue项目存在各种loader,有一部loader由于业务代码问题,打包时间非常久,这里可以通过 thread-loader 进行优化,因为它能将这些非常耗时的内容单独放到另一个线程中执行,和其他代码同步进行执行,节省打包时间.

建议 :仅在耗时的loader中使用 thread-loader ,因为开启多线程意味着系统中会存在多个worker ,对于node.js 而言,过多的worker其开销会导致性能降低,同时还会限制跨进程的数据交换等。

未启动时,我们可以看到打包耗时6.41 secs

针对babel-loader进行多线程配置

js 复制代码
module.exports = {
    configureWebpack: {
        // ...省略
        module: {
            rules: [
              {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                  'babel-loader',
                  {
                    loader: 'thread-loader',
                    options: {
                      // 指定 worker 的数量
                      workers: 2
                    }
                  }
                ]
              }
            ]
          }
    },
    // 省略
}

启动后,我们可以看到打包耗时降低至 2.41 secs

2.2 利用 hard-source-webpack-plug 生成项目缓存

生成缓存位置在node_moudule下的.cache,

补充:如果没有显示,请到文件系统下勾选显示隐藏文件

vue-cli 已经内置了 cache-loaderbabel-loader的缓存方式,在这里我们讨论配置 hard-source-webpack-plugr

js 复制代码
// npm i hard-source-webpack-plugin --save-dev
module.exports = {
    configureWebpack: {
        // ...省略
        plugins: [
            new SpeedMeasurePlugin(),
            new BundleAnalyzerPlugin(),
            new HardSourceWebpackPlugin({
              root: process.cwd(),
              directories: [],
              environmentHash: {
                root: process.cwd(),
                directories: [],
                files: ['package.json', 'yarn.lock']
              }
            })
        ],
    // 省略
}

首次打包,通过下图我们可以看,首次打包的时间不减反增了,看到这里我们可以知道,hard-source-webpack-plug的作用是后续打包可以利用缓存进行加速,首次打包会将打包时间增加
如果node_moudule下存在.cache,则将.cache删除模拟首次打包

首次打包后,项目下已存在缓存文件,再次进行打包速度大大降低

2.3 缩小打包的体积

减少代码体积的方式主要如下:

  • 使用terser减少代码体积

  • 优化模块查找路径

  • 通过 image-webpack-plugin 或 image-minimizer-webpack-plugin 进行图片资源的压缩

  • splitChunks(dllplugin)提取第三方库 (webpack4或以上没必要使用dllplugingithub.com

  • 开启Gzip 压缩

2.3.1.虽然UglifyJs也能进行console.log()的清除,但UglifyJs无人维护了,相比之下,terser仍在维护,并且功能上比后者强大很多

补充:建议使用terser-webpack-plugin来配置terser,此处为配置terser

js 复制代码
chainWebpack: config => {
      config.optimization.runtimeChunk('single')
      config.optimization
        .minimize(true)
        .minimizer('terser')
        .tap((args) => {
          const {
            terserOptions
          } = args[0]
          // 移除 console
         terserOptions.compress.drop_console = true
          // 移除 debugger
          terserOptions.compress.drop_debugger = true
          return args
        })
      },
2.3.2 通过配置优化模块查找路径进行打包优化
  • 通过modules指定查找第三方模块的路径。
  • 通过alias指定第三方模块直接查找到打包构建好的压缩js文件。
  • 通过 module.noParse 配置哪些模块文件的解析可以忽略。通常用于配置那些体积庞大、但是没有依赖的第三方库,以提高构建性能。例如,对于一些大型的类库文件,比如 jQuery 或者 Lodash,它们本身并不依赖其他模块,因此可以通过 module.noParse 配置告诉 webpack 不需要解析它们,从而加快构建速度。
js 复制代码
configureWebpack: {
        resolve: {
            modules: [path.resolve(__dirname, 'node_modules')],
            alias: {
                //配置别名
                'assets': '@/assets',
                'common': '@/common',
                'components': '@/components',
                'network': '@/network',
                'views': '@/views',
                'pluginunit':'@/pluginunit'
            }
        },
        module: {
             noParse:/^(vue|vue-router|vuex|vuex-router-sync)$/,
          }
  }
2.3.3 通过在构建过程中压缩图像,从而减小最终输出文件的体积,提高页面加载速度
js 复制代码
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
  chainWebpack: config => {
      config.plugin('image').use(ImageMinimizerPlugin, [{
        minimizerOptions: {
          plugins: [
            ['gifsicle', {
              interlaced: true
            }],
            ['jpegtran', {
              progressive: true
            }],
            ['optipng', {
              optimizationLevel: 5
            }],
            ['svgo', {
              plugins: [{
                removeViewBox: false,
              }, ],
            }, ],
          ],
        },
      }, ]);
  },
};
2.3.4 通过splitChunks进行代码分割

splitChunks 是 webpack 中的一个优化功能,用于将公共模块提取到单独的文件中,以便在多个入口文件之间共享。通过将公共模块提取到单独的文件中,可以减小最终输出文件的体积,提高页面加载速度。

在 webpack 4 中,splitChunks 取代了之前的 CommonsChunkPlugin 插件,提供了更灵活的配置选项。通过 splitChunks,可以配置哪些模块应该被提取,以及如何命名和缓存这些提取出来的文件。

js 复制代码
module.exports = { 
chainWebpack: config => {
    config.optimization.splitChunks({
      chunks: 'all',
      cacheGroups: {
        libs: {
          name: 'chunk-libs',
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: 'initial' 
        },
        elementUI: {
          name: 'chunk-elementUI', 
          priority: 20, 
          test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
        },
        commons: {
          name: 'chunk-commons',
          test: resolve('src/components'),
          minChunks: 3, 
          priority: 5,
          reuseExistingChunk: true
        }
      }
    })
}
2.3.5 开启Gzip 压缩

在 Vue CLI 项目中开启 Gzip 压缩,从而减小最终输出文件的体积,提高页面加载速度。

js 复制代码
npm install compression-webpack-plugin --save-dev

const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  configureWebpack: {
    plugins: [
      new CompressionPlugin({
        test: /\.js$|\.html$|\.css/,
        threshold: 10240,
        deleteOriginalAssets: false
      })
    ]
  }
};

2.3.5 最后

以上是一些基于 vue-cli(基于 webapck) 进行的一些常见优化,但其他优化还有很多,其中包括

  • 对较大模块使用externals 配置选项,进行cdn配置,将大模块摘除在打包之外
  • 将本地图片进行精灵图拼接,提升图片加载速度
  • 等等...

很多时候优化vue-cli主要取决于自己需要的场景,像配置cdn,在某些隔离外网的项目中,就不能进行配置,搞了这么多优化手段,其实还不如我前老大说的,增大服务器配置,一台好的服务器能抵消你一大片配置上的优化。

也不知道都2024年了,还有没有人看看vue-cli配置。

相关推荐
10年前端老司机1 小时前
什么!纯前端也能识别图片中的文案、还支持100多个国家的语言
前端·javascript·vue.js
摸鱼仙人~1 小时前
React 性能优化实战指南:从理论到实践的完整攻略
前端·react.js·性能优化
程序员阿超的博客2 小时前
React动态渲染:如何用map循环渲染一个列表(List)
前端·react.js·前端框架
magic 2452 小时前
模拟 AJAX 提交 form 表单及请求头设置详解
前端·javascript·ajax
小小小小宇6 小时前
前端 Service Worker
前端
只喜欢赚钱的棉花没有糖7 小时前
http的缓存问题
前端·javascript·http
小小小小宇7 小时前
请求竞态问题统一封装
前端
loriloy7 小时前
前端资源帖
前端
源码超级联盟7 小时前
display的block和inline-block有什么区别
前端
GISer_Jing7 小时前
前端构建工具(Webpack\Vite\esbuild\Rspack)拆包能力深度解析
前端·webpack·node.js