Vue打包优化

127 阅读2分钟

初始打包时间: 初始打包时长.png

初始包体积:

初始包体积.png

1. 包分析工具

插件使我们能够更直观的看到每个包的大小以及构建时长。
1-1. 插件
webpack-bundle-analyzer:这会生成一个视图,以便更直观的观察包
speed-measure-webpack-plugin

1-2. 安装
npm install webpack-bundle-analyzer --save-dev
npm install speed-measure-webpack-plugin --save-dev

更改package.json中的build

"scripts": {
  "build": "vue-cli-service build --report",
},

2. 以CDN形式引入公共依赖

使用 externals 提取这些依赖包,在打包时忽略它们,就不会再打到 chunk-vendors.js里边; 更改为以CDN的形式引入。

module.exports = {
  transpileDependencies: true,
  productionSourceMap: true,
  publicPath: './',
  configureWebpack: {
    // 提取公共依赖
    externals: {
      vue: 'Vue',
      'element-ui': 'ELEMENT' 
    },
    plugins: [
      new BundleAnalyzerPlugin(),
      new SpeedMeasurePlugin(),
    ],
  },
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

注意:这里演示的将elementUI提取出来,只是为了演示。正常开发中,最佳实践为按需引入(使用了哪些就引入哪些)

3. 开启代码压缩

开启压缩有两种方式:
a. 在打包时压缩,当请求网页时,会返回对应的.gz文件;
b. 在nginx中配置,请求网页时,由服务器进行压缩。
建议使用第一种,第二种需要消耗服务器的 CPU 资源。

3-1. 插件
compression-webpack-plugin

3-2. 安装
npm install compression-webpack-plugin --save-dev

本地项目配置

const CompressionPlugin = require('compression-webpack-plugin'); // 代码压缩

module.exports = {
  configureWebpack: {
    plugins: [
      new CompressionPlugin(
        {
          algorithm: "gzip",
          test: /\.(js|css)$/, // 匹配的文件类型
          threshold: 10240, // 对10k以上的文件压缩
          // 是否删除源文件,这里不要删除源文件哈。
          // 因为nginx中是找对应js的gz文件,如果删除,会导致ng找不到对应文件,从而页面加载失败。
          deleteOriginalAssets: false,
          minRatio: 0.8, // 压缩比
        }
      ),
    ],
  },
}

服务器上的nginx配置:

http {
    # ......
    # 开启nginx_static后,对于任何文件都会先查找是否有对应的gz文件。
    gzip_static on;

    # ......
}

怎么判断配置压缩生效?
响应标头中的 Content-Encodinggzip 时说明配置生效。

4. production环境不生成SourceMap

module.exports = {
  productionSourceMap: process.env.NODE_ENV !== 'production',
  configureWebpack: {
    // ......
  },
}

5. Happywebpack(开启多线程打包)

开启多线程打包这一步在大型项目中的效果最为显著。

5-1. 插件
HappyPack

5-2. 安装
npm install happypack --save-dev

const HappyPack = require('happypack');
const os = require('os');
// 开辟一个线程池,拿到系统CPU的核数,happypack 将编译工作利用所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module.exports = {
  configureWebpack: {
    plugins: [
      new HappyPack({
        id: 'happybabel',
        loaders: ['babel-loader'],
        threadPool: happyThreadPool
      })
    ],
  },
}

------------------------ 结束 ------------------------

完整配置

const path = require('path');

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // 包分析(会提供一个网页视图,更直观的观察包的体积信息)
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 包分析

const CompressionPlugin = require('compression-webpack-plugin'); // 代码压缩

const HappyPack = require('happypack');
const os = require('os');
// 开辟一个线程池,拿到系统CPU的核数,happypack 将编译工作利用所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module.exports = {
  transpileDependencies: true,
  productionSourceMap: process.env.NODE_ENV !== 'production',
  publicPath: './',
  configureWebpack: {
    externals: {
      vue: 'Vue',
      'element-ui': 'ELEMENT' 
    },
    plugins: [
      new BundleAnalyzerPlugin(),
      new SpeedMeasurePlugin(),
      new CompressionPlugin(
        {
          algorithm: "gzip",
          test: /\.(js|css)$/, // 匹配的文件类型
          threshold: 10240, // 对10k以上的文件压缩
          deleteOriginalAssets: false, // 是否删除源文件,这里不要删除源文件哈,因为nginx中是找对应js的gz文件,如果删除,会导致ng找不到对应文件,从而页面加载失败。
          minRatio: 0.8, // 压缩比
        }
      ),
      new HappyPack({
        id: 'happybabel',
        loaders: ['babel-loader'],
        threadPool: happyThreadPool
      })
    ],
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
      }
    },
  },
}

优化结果

优化后打包时间:

优化后打包时长.png

打包时长:11.33s ==> 3.54s
打包时长缩短:69%

优化后包体积:

优化后包体积.png

打包体积:5.63M ==> 954KB
减少体积:83%

还有很多优化方式,后续再记录上去,拜了个拜!