开发环境性能优化
- 优化打包构建速度(HMR)
HMR:hot module replacement 热模块替换,一个模块发生变化,只会重新打包变化的模块,而不是所有模块,提升构建速度
1、样式文件可以使用HMR功能,只要在loader 中使用style-loader
{
// 处理css资源
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
2、js 文件 默认不能使用HMR功能需要修改js 添加支持HMR 功能的代码,但是只能处理非入口js文件的其他文件
if (module.hot) {
// 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
module.hot.accept('./print.js', function() {
// 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
// 会执行后面的回调函数
print();
});
}
3、HTML 文件默认不能使用HMR 一般不需要做热更新。
entry: ['./src/js/index.js', './src/index.html'],
- 优化代码调试(source-map)
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
devtool: 'eval-source-map'
类型 | 作用范围 |
---|---|
source-map | 映射单独的外部文件,能错误代码准确信息和源代码的错误位置 |
inline-source-map | 映射一个单独内联source-map,错误代码准确信息和源代码的错误位置 |
hidden-source-map | 映射单独的外部文件,错误代码错误原因,但是没有错误位置,不能追踪源代码错误,只能提示到构建后代码的错误位置 |
eval-source-map | 每一个文件都生成对应的source-map,都在eval 错误代码准确信息 和 源代码的错误位置 |
nosources-source-map | 错误代码准确信息, 但是没有任何源代码信息 |
cheap-source-map | 错误代码准确信息 和 源代码的错误位置, 只能精确到行 |
cheap-module-source-map | 错误代码准确信息 和 源代码的错误位置 |
生产环境性能优化
- 优化打包构建速度
1、oneOf
当一个文件只需要被一个loader 处理时,使用oneOf 只会匹配一个loader
oneOf: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
]
2、多进程打包
开启多进程打包。 只有工作消耗时间比较长,才需要多进程打包
{
loader: 'thread-loader',
options: {
workers: 2 // 进程2个
}
}
3、externals
把不行打包文件排除
externals: {
// 拒绝jQuery被打包进来
jquery: 'jQuery'
}
4、dll
(1)需要运行 webpack.dll.js 文件
使用dll技术,对某些库(第三方库:jquery、react、vue…)进行单独打包
当你运行 webpack 时,默认查找 webpack.config.js 配置文件
–> webpack --config webpack.dll.js
plugins: [
// 打包生成一个 manifest.json --> 提供和jquery映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射库的暴露的内容名称
path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
})
],
(2)告诉webpack哪些库不参与打包,同时使用时的名称也得变
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, 'dll/manifest.json')
}),
(3)将某个文件打包输出去,并在html中自动引入该资源
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
- 优化代码运行的性能
1、缓存(hash-chunkhash-contenthash)
babel缓存设置 cacheDirectory: true 可以让第二次打包构建速度更快
// 第二次构建时,会读取之前的缓存
cacheDirectory: true
文件资源缓存
(1) hash: 每次wepack构建时会生成一个唯一的hash值。
问题: 因为js和css同时使用一个hash值。
(2) chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题: js和css的hash值还是一样的
因为css是在js中被引入的,所以同属于一个chunk
(3) contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
}
2、tree shaking
tree shaking:去除无用代码;
前提:1. 必须使用ES6模块化 2. 开启production环境
作用: 减少代码体积
问题:可能会把css / @babel/polyfill (副作用)文件干掉
在package.json中配置 “sideEffects”: [".css", ".less"]
"sideEffects": [
"*.css"
]
3、code spilt
(1)配置入口// entry
// 单入口
// entry: './src/js/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个bundle
index: './src/js/index.js',
test: './src/js/test.js'
},
(2)设置 optimization
/*
1. 可以将node_modules中代码单独打包一个chunk最终输出
2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
*/
optimization: {
splitChunks: {
chunks: 'all'
}
},
(3) import动态导入语法
/*
通过js代码,让某个文件被单独打包成一个chunk
import动态导入语法:能将某个文件单独打包
*/
import(/* webpackChunkName: 'test' */'./test')
.then(({
mul, count }) => {
// 文件加载成功~
// eslint-disable-next-line
console.log(mul(2, 5));
})
.catch(() => {
// eslint-disable-next-line
console.log('文件加载失败~');
});
4、懒加载 预加载
// 懒加载:当文件需要使用时才加载
// 预加载 :会在使用之前,提前加载js文件
// 正常加载可以认为是并行加载(同一时间加载多个文件)
// 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(({
mul }) => {
console.log(mul(4, 5));
});
5、PWA
PWA: 渐进式网络开发应用程序(离线可访问)
workbox --> workbox-webpack-plugin
new WorkboxWebpackPlugin.GenerateSW({
/*
1. 帮助serviceworker快速启动
2. 删除旧的 serviceworker
生成一个 serviceworker 配置文件~
*/
clientsClaim: true,
skipWaiting: true
})