vue项目优化之打包速度

本周接到一个优化项目打包速度的任务,开始我是一脸懵逼的,之前未曾做过类似的任务,而且对webpack配置也不是太精通。头疼之际,google了网上大神的意见,并以身试毒,这里面有很多坑,现总结一下我用到的优化方式

优化后对比

我们先看看优化之前的打包时间:62.74s
image.png

优化之后的打包时间:18.24
image.png

优化方法

配置includeexclude

  • 使用 include 精确指定要处理的目录,这可以减少不必要的遍历,从而减少性能损失。
  • 使用 exclude 对已明确知道的,不需要处理的目录,予以排除,从而进一步提升性能
 rules: [
    {
      test: /\.vue$/,
      loader: 'vue-loader',
      options: vueLoaderConfig,
      include: [resolve('src'), resolve('node_modules/vue-easytable/libs')],
      exclude: /node_modules\/(?!(autotrack|dom-utils))|vendor\.dll\.js/
    },
    {
      test: /\.js$/,
      loader: 'babel-loader',
      include: [resolve('src')],
      exclude: /node_modules/
    },

css-loader使用0.15.0以下的版本

个版本以上的速度会慢许多,不过在我的项目中还没看到明显变化

使用 HappyPack

运行在 Node.js 之上的 Webpack 是单线程模型的,也就是说 Webpack 需要处理的任务需要一件件挨着做,不能多个事情一起做。

那能不能让 Webpack 同一时刻处理多个任务,发挥多核 CPU 电脑的威力,以提升构建速度呢?

HappyPack 就能让 Webpack 做到这点,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。

// 接入happypack
const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })
var vueLoaderConfig = require('./vue-loader.conf')

module.exports = {
 module: {
    rules: [{
        test: /\.css$/,
        loader: 'happypack/loader?id=css'
      }, {
        test: /\.less$/,
        loader: 'happypack/loader?id=less'
      },
      {
        test: /\.vue$/,
        loader: 'happypack/loader?id=vue'
      },
      {
        test: /\.js$/,
        loader: 'happypack/loader?id=js',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'happypack/loader?id=font'
      }
    ]
  },
  plugins: [
    new HappyPack({
      id: 'css',
      loaders: [{
        loader: require.resolve('css-loader'),
          options: {
            importLoaders: 1,
            minimize: true,
            sourceMap: true
          }
        }
      ],
      threadPool: happyThreadPool,
      verbose: false
    }),
    new HappyPack({
      id: 'less',
      loaders: [{
        loader: require.resolve('css-loader'),
          options: {
            importLoaders: 1,
            minimize: true,
            sourceMap: true
          }
        }, {
          loader: require.resolve('less-loader'),
        }
      ],
      threadPool: happyThreadPool,
      verbose: false
    }),
    new HappyPack({
      id: 'vue',
      loaders: [{
        loader: 'vue-loader',
        options: vueLoaderConfig
      }],
      threadPool: happyThreadPool,
      verbose: false
    }),
    new HappyPack({
      id: 'js',
      loaders: [{
        loader: 'babel-loader?cacheDirectory=true'
      }],
      threadPool: happyThreadPool,
      verbose: false
    }),
    new HappyPack({
      // 用id来标识 happypack处理那里类文件
      id: 'font',
      // 如何处理  用法和loader 的配置一样
      loaders: [{
        loader: 'url-loader?cacheDirectory=true',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }],
      //共享进程池
      threadPool: happyThreadPool,
      // 允许 HappyPack 输出日志
      verbose: false
    }),
  ],
};

以上代码有两点重要的修改:

  • 在 Loader 配置中,所有文件的处理都交给了 happypack/loader 去处理,使用紧跟其后的 querystring ?id=babel 去告诉 happypack/loader 去选择哪个 HappyPack 实例去处理文件。
  • 在 Plugin 配置中,新增了两个 HappyPack 实例分别用于告诉 happypack/loader 去如何处理 .js 和 .css 文件。选项中的 id 属性的值和上面 querystring 中的 ?id=babel 相对应,选项中的 loaders 属性和 Loader 配置中一样。

它对file-loader和url-loader支持不好,所以这两个loader就不需要换成happypack了


文章作者: 徐辉波
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 徐辉波 !
评论
 上一篇
Flutter学习 (一) Flutter学习 (一)
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
2018年12月01日
下一篇 
webpack学习 webpack学习
前言: 什么是Webpack WebPack可以看做是__模块打包机__:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式
2018年11月21日
  目录