Webpack的几点性能优化

Webpack的性能优化主要从打包时间和打包出来的包的大小来考虑html


减小 Webpack 打包时间

优化 Loader

对于打包来讲,loader越多说明代码须要转换的越多,则效率就越低,所以在优化loader的时候,能够选择loader的搜索范围。vue

module.exports = {
  module: {
    rules: [
      {
        // js 文件才使用 babel
        test: /\.js$/,
        loader: 'babel-loader',
        // 选择范围,只在 src 文件夹下查找
        include: [resolve('src')],
        // 选择范围,不会去查找的路径
        exclude: /node_modules/
      }
    ]
  }
}
复制代码

为何不去查找node_modules路径下的文件呢?由于node_modules中使用的代码都是编译过的,所以无必要再去处理一下。node

同时,还能够将Babel编译过的文件缓存起来,在下次须要编译更改过的代码文件就能够,这样能够大大减小打包的时间webpack

loader: 'babel-loader?cacheDirectory=true'
复制代码

提早打包后引入

DllPluginDllReferencePlugin能够将一些不作修改的依赖文件,提早打包,只有当类库更新版本才有须要从新打包,而且也实现了将公共代码抽离成单独文件的优化方案。web

new webpack.DllPlugin({
  context: __dirname,
  name: "[name]_[hash]",
  path: path.join(__dirname, "manifest.json"),
})复制代码

new webpack.DllReferencePlugin({
  context: __dirname, //文件中请求的上下文
  manifest: require("./manifest.json"), //生成manifest.json文件
  name: "./my-dll.js", //暴露的名称(可选)
  scope: "xyz", //用于访问dll的内容(可选)
  sourceType: "commonjs2" //dll是如何暴露的 (可选)
})复制代码

//webpack.dll.conf.js

const path = require('path');
const webpack = require('webpack');
module.exports = {
  entry: {
    vendor: [
    'vue/dist/vue.esm.js',
    'vue-router',
    'vuex',
    'babel-polyfill' //提早打包一些基本不怎么修改的文件
    ]
  },
  output: {
    path: path.join(__dirname, '../static/js'), //放在项目的static/js目录下面
    filename: '[name].dll.js', //打包文件的名字
    library: '[name]_library' //可选 暴露出的全局变量名
    // vendor.dll.js中暴露出的全局变量名。
    // 主要是给DllPlugin中的name使用,
    // 故这里须要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'), //生成上文说到清单文件,放在当前build文件下面,这个看你本身想放哪里了。
      name: '[name]_library'
    }),  
    //压缩 只是为了包更小一点 
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        drop_console:true,
        drop_debugger:true
      },
      output:{
        // 去掉注释内容
        comments: false,
      },
      sourceMap: true
    })
  ]
};复制代码

//webpack.pro.conf.js 

const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

  new webpack.DllReferencePlugin({
      context: path.resolve(__dirname, '..'), 
      manifest: require('./vendor-manifest.json')
    }),
    //这个主要是将生成的vendor.dll.js文件加上hash值插入到页面中。
    new AddAssetHtmlPlugin([{
      filepath: path.resolve(__dirname,'../dist/static/js/vendor.dll.js'),
      outputPath: utils.assetsPath('js'),
      publicPath: path.posix.join(config.build.assetsPublicPath, 'static/js'),
      includeSourcemap: false,
      hash: true,
    }]),复制代码

npm run build:dll  //这个命令在最初执行一次以后,以后发布都不须要再重复执行了,除非webpack.dll.conf.js里面的依赖文件有升级。
//发布以前的打包
npm run build 复制代码

代码压缩

使用UglifyJS 来压缩代码,由于这个是单线程运行的,为了加快效率,能够使用webpack-parallel-uglify-plugin来并行运行UglifyJS,从而提升效率。vue-router

在 Webpack4 中,咱们就不须要以上这些操做了,只须要将 mode 设置为 production 就能够默认开启以上功能。
vuex

还有须要注意的是:npm

resolve.extensions:用来代表文件后缀列表,默认查找顺序是 ['.js', '.json'],若是你的导入文件没有添加后缀就会按照这个顺序查找文件。咱们应该尽量减小后缀列表长度,而后将出现频率高的后缀排在前面json

resolve.alias:能够经过别名的方式来映射一个路径,能让 Webpack 更快找到路径缓存


减小 Webpack 打包后的文件体积

Scope Hoisting

Scope Hoisting会分析出模块之间的的依赖关系,尽量的把打包出来的模块合并到一个函数中

// test.js
export const a = 1
// index.js
import { a } from './test.js'
复制代码

对于这种状况,咱们打包出来的代码会相似这样

[
  /* 0 */
  function (module, exports, require) {
    //...
  },
  /* 1 */
  function (module, exports, require) {
    //...
  }
]
复制代码

可是若是使用 Scope Hoisting 的话,代码就会尽量的合并到一个函数中去,也就变成了这样的相似代码

[
  /* 0 */
  function (module, exports, require) {
    //...
  }
]复制代码

若是在 Webpack4 中你但愿开启这个功能,只须要启用 optimization.concatenateModules 就能够了

odule.exports = {
  optimization: {
    concatenateModules: true
  }
}
复制代码
相关文章
相关标签/搜索