系列文章目录
webpack构建项目(一)框架搭建
webpack构建项目(二)打包实战
文章目录
前言
webpack优化性能有两个大方面:开发环境性能优化和生产环境性能优化。
这两个方面的优化方向又是不同的。
开发环境性能优化
我们希望能更快打包,那就优化打包构建速度,用到了 HMR 技术
我们希望能更方便调试,优化代码调试,就用到 source-map 技术。
生产环境性能优化
①优化打包构建速度:oneOf、babel缓存、多进程打包、externals、dll
②优化代码运行: 缓存(hash-chunkhash-contenthash)、tree shaking(树摇)、code split(代码分割)、懒加载/预加载、pwa。
接下来会一个个的去介绍这些方法
一、开发环境性能优化
1.1 优化打包构建速度
1.1.1 HMR
Hot Module Replacement 模块热替换
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块)
①实现方法:
target: "web",
devServer: {
// 开启HMR 功能
// 当修改了webpack 配置,新配置要想生效,必须重新webpack 服务
hot: true,
}
②样式文件:style-loader 内置HMR功能
③js文件:默认不能使用HMR功能。需要添加支持HMR功能的代码
注意:HMR功能只能处理非入口js文件的其他文件。
if (module.hot) {
// 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
module.hot.accept("./print.js", function () {
// 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
// 会执行后面的回调函数
print();
});
}
④html文件: 默认不能使用HMR功能(不用做HMR功能).同时会导致问题
解决:修改entry入口,将html文件引入
entry: ["./src/js/index.js", "./src/index.html"]
1.2 优化代码调试
1.2.1 source-map
source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
source-map有很多类型:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
类型 | 作用 |
---|---|
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:外部 | 错误代码准确信息 和 源代码的错误位置 module会将loader的source map加入 |
内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快
① 开发环境需求:速度快,调试更友好
速度快(eval>inline>cheap>...)
eval-cheap-souce-map
eval-source-map
调试更友好
souce-map
cheap-module-souce-map
cheap-souce-map
开发环境推荐: eval-source-map / eval-cheap-module-souce-map
② 生产环境需求:内联会让代码体积变大,所以在生产环境不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息
生产环境推荐: source-map / cheap-module-souce-map
二、生产环境性能优化
2.1 优化代码运行
2.1.1 文件资源缓存
① hash: 每次wepack构建时会生成一个唯一的hash值。
问题: 因为js和css同时使用一个hash值。
如果重新打包,会导致所有缓存失效。(虽然只改动一个文件)
② chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题: js和css的hash值还是一样的。
因为css是在js中被引入的,所以同属于一个chunk。
③ contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
这样让代码上线运行缓存更好使用。
output: {
filename: "js/built.[contenthash:10].js",
path: resolve(__dirname, "build"),
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/built.[contenthash:10].css",
})
]
2.1.2 code split
代码分割:将一个大的文件分割成多个文件 【可以实现按需加载】
① 方法一:多入口
// 单入口
// entry: './src/js/index.js',
entry: {
// 多入口:有一个入口,最终输出就有一个bundle
index: "./src/js/index.js",
test: "./src/js/test.js",
},
output: {
// [name]:取文件名
filename: "js/[name].[contenthash:10].js",
path: resolve(__dirname, "build"),
}
② 方法二 加一个optimization配置项
将node_modules中代码单独打包一个chunk最终输出
/*
1. 可以将node_modules中代码单独打包一个chunk最终输出
2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
*/
optimization: {
splitChunks: {
chunks