前端项目工程化:项目打包构建优化(二)

178 阅读3分钟

上章我们讲了工程化中vue的升级改造,今天这章我们来谈谈项目打包构建优化

构建性能优化方法

  • 查找并诊断性能瓶颈:
    • 构建速度分析:影响构建性能和开发效率
    • 构建体积分析:影响页面访问性能
  • 构建性能优化常用方法:
    • 通过多进程加快构建速度
    • 通过分包减小构建目标容量
    • 减少构建目标加快构建速度

构建速度分析speed-measure-webpack-plugin

首先安装

npm install --save-dev speed-measure-webpack-plugin

然后在vue.config.js里写入

const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin({})
具体使用方式
configureWebpack: smp.wrap({
     resolve: {
       alias: {
         components: '@/components'
       }
     }
   }),

然后运行

npm run build

结果(根据实际情况来此为演示) image.png 我们开到在打包的过程中,每一个依赖打包所需的时长,可以选择性的进行优化。

具体应用请参考speed-measure-webpack-plugin - npm (npmjs.com)

构建体积分析 webpack-bundle-analyzer

安装

npm install webpack-bundle-analyzer -D

启动后可以看到各个模块的体积

image.png

多进程打包 thread-loader

多进程打包:某个任务消耗时间较长会卡顿,多进程可以同一时间干多件事,效率更高。

优点是提升打包速度,缺点是每个进程的开启和交流都会有开销(babel-loader消耗时间最久,所以使用thread-loader针对其进行优化)

PS:如果你的项目本身就很小,最好不要使用thread-loader,反而会增加打包时间消耗进程。

安装

npm install --save-dev thread-loader

用法

把这个 loader 放置在其他 loader 之前, 放置在这个 loader 之后的 loader 就会在一个单独的 worker 池(worker pool)中运行

在 worker 池(worker pool)中运行的 loader 是受到限制的。例如:

  • 这些 loader 不能产生新的文件。
  • 这些 loader 不能使用定制的 loader API(也就是说,通过插件)。
  • 这些 loader 无法获取 webpack 的选项设置。

每个 worker 都是一个单独的有 600ms 限制的 node.js 进程。同时跨进程的数据交换也会被限制。

请仅在耗时的 loader 上使用

示例

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /.js$/,
        include: path.resolve("src"),
        use: [
          "thread-loader",
          "expensive-loader"
        ]
      }
    ]
  }
}

可配选项

use: [
  {
    loader: "thread-loader",
    // 有同样配置的 loader 会共享一个 worker 池(worker pool)
    options: {
      // 产生的 worker 的数量,默认是 cpu 的核心数
      workers: 2,

      // 一个 worker 进程中并行执行工作的数量
      // 默认为 20
      workerParallelJobs: 50,

      // 额外的 node.js 参数
      workerNodeArgs: ['--max-old-space-size', '1024'],

      // 闲置时定时删除 worker 进程
      // 默认为 500ms
      // 可以设置为无穷大, 这样在监视模式(--watch)下可以保持 worker 持续存在
      poolTimeout: 2000,

      // 池(pool)分配给 worker 的工作数量
      // 默认为 200
      // 降低这个数值会降低总体的效率,但是会提升工作分布更均一
      poolParallelJobs: 50,

      // 池(pool)的名称
      // 可以修改名称来创建其余选项都一样的池(pool)
      name: "my-pool"
    }
  },
  "expensive-loader"
]

预热

可以通过预热 worker 池(worker pool)来防止启动 worker 时的高延时。

这会启动池(pool)内最大数量的 worker 并把指定的模块载入 node.js 的模块缓存中。

const threadLoader = require('thread-loader');

threadLoader.warmup({
  // pool options, like passed to loader options
  // must match loader options to boot the correct pool
}, [
  // modules to load
  // can be any module, i. e.
  'babel-loader',
  'babel-preset-es2015',
  'sass-loader',
]);

其实vue也提供了parallel这一定义,有兴趣可以去了解下。主要用途:

  1. 是否为 Babel 或 TypeScript 使用 thread-loader。
  2. 该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建

今天就到这了,下期再见~