Webpack的性能优化主要从打包时间和打包出来的包的大小来考虑html
对于打包来讲,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'
复制代码
DllPlugin和DllReferencePlugin能够将一些不作修改的依赖文件,提早打包,只有当类库更新版本才有须要从新打包,而且也实现了将公共代码抽离成单独文件的优化方案。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 更快找到路径缓存
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
}
}
复制代码