分析工具
体积优化
- JS压缩
- CSS压缩
- 图片压缩
- 拆分代码
速度优化
开发环境优化
HMR(hot module replacement) 热模块替换
- 作用:一个模块发生变化,只会重新打包这个模块(其他不变),提高构建速度
- 样式文件:可以使用HMR功能,因为使用style-loader内部实现了
- Js文件:默认不能使用HMR功能---》需要修改js代码,添加支持HMR功能的代码 注意:HMR功能对JS文件的处理,只能处理非入口js文件的其他文件。
- html文件:默认不能使用HMR功能,同时会导致问题:html文件不能热更新了。解决:修改entry入口,将html文件引入
const webpack = require('webpack')
module.exports = {
...
devServer:{
hot:true,
hotOnly:true
},
plugins:{
new webpack.HotModuleReplacementPlugin()
}
}
source map
source map :一种提供源代码到构建后代码映射技术(如果构建后代码出错了,通过映射可以追踪源代码错误)
module.exports = {
....
devtool:'source-map'
}
生产环境优化
oneOf
- 作用:一个文件不会被多个loader匹配
- 注意:不能有两个配置处理同一种类型文件 比如:对于js文件的eslint-loader和babelloader,可以把先执行的eslint-loader放在oneOf的上方
module.exports = {
...
rules:[
{
test:/\.js$/,
loader:'eslint-loader',
}
oneOf:[
{
test:/\.js$/,
loader:'babel-loader',
}
]
]
}
缓存
- babel缓存:cacheDirectory:true ---》让第二次打包构建速度更快
module.exports = {
...
rules:[
{
test:/\.js$/,
loader:'babel-loader',
options:{
//开启babel缓存,第二次构建时,会读取之前的缓存
cacheDirectory:true
}
}
]
}
- 文件资源缓存 hash:每次webpack构建时会生成一个唯一的hash值 问题一:因为js和css同时使用同一个hash值,如果重新打包,会导致所有缓存失效。 解决:chunkhash,根据chunk生成的hash值。但是还是会出现问题: js和css的hash值还是一样的,因为css时在js中被引入,所以同属于一个chunk. 解决:contenthash:根据文件的内容生成hash值。不同文件hash值不一样。 ---> 让代码上线运行缓存更好使用
module.exports = {
...
entry:'./src/index.js',
output:{
filename:'js/built.[contenthash:10].js'
},
...
plugins:[
new MiniCssExtractPlugin({
filename:'css/built.[contenthash:10].css'
})
]
}
tree shaking
作用:去除无用代码 条件:必须使用Es6模块化,开启production环境
在package.json中配置
"sideEffects":false 所有代码都没有副作用(都可以进行tree shaking)
问题:可能会把css/@babel/polyfill(副作用)文件去除
"sideEffects":["*.css","*.less"]
分离
- code split(代码分割) 作用:可以把代码分离到不同的bundle中,实现按需加载或并行加载文件。代码 分离可以用于获取更小的bundle,以及控制资源加载优先级,提高加载时间。
- bundle split 过程:创建多个更小的文件,并行加载,以获得更好的缓存效果。 作用:使浏览器并行下载,提高下载速度。运用浏览器缓存,只要代码被修改,文件名中的哈希值改变了才会去再次加载。
PWA(Progressive Web Application) 离线访问技术
webpack配置使用workbox-webpack-plugin插件,生成一个serviceWorker配置文件
安装插件:npm i worker-webpack-plugin
引入插件:const worboxWebpackPlugin = require('worker-webpack-plugin')
module.exports = {
...
plugins:[
new WorkboxWebpackPlugin.GenerateSW({ //生成一个serviceworker配置文件
clientsClaim:true,// 帮助serviceworker快速启动
skipWaiting:true,// 删除旧的serviceworker
})
]
}
在入口文件index.js中注册serviceWorker
if('serviceWorker' in navigator){
window.addEventListener('load',()=>{
navigator.serviceWorker.register('/service-worker.js')
.then(()=>{
// do something
}).catch(()=>{
// do something
})
})
}
修改package.json中eslintConfig配置(因为eslint不认识window,navigator等全局变量)
"eslintConfig":{
"env":{
"browser":true,//支持浏览器的全局变量
}
}
serviceWorker必须运行在服务器上,需要启动服务器
1:通过nodejs运行
2:安装npm i serve -g
serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
externals
防止将某些import的包(package)打包到bundle中,而是在运行时再去从外部获取这些扩展依赖
module.exports = {
...
externals:{
// 拒绝打包时引入
jquery:'jQuery',
}
}
但是需要在index.html文件中手动引入
优化构建速度
- 缩小文件的搜索范围
- resolve字段告诉webpack怎么去搜索文件
- module。noParse字段告诉webpack不必解析那些文件,排除对非模块库文件的解析
- 配置loader,通过test、exclude、include 缩小搜索范围
- 使用DIIPlugin减少基础模块编译次数
- 使用HappyPack开启多进程Loader转换
- 运行在Node.js之上的Webpack是单线程模型,只能一个一个文件处理,不能并行处理。HappyPack可以将任务分解给多个子进程,最后将结果发给主进程。
- 使用ParalleUglifyPlugin开启多进程压缩JS文件
- ParalleUglifyPlugin可以开启多个子进程,每个子进程使用UglifyJS压缩代码,并行执行
优化开发体验
- webpack监听文件
- 1.启动webpack时加上--watch参数
- 2.在配置文件中设置watch:true。合理设置watchOptions可以优化监听体验。
- 开启模块热替换HMR
- DevServer刷新浏览器
优化输出质量-压缩文件体积
- 区分环境---减少生成环境代码体积
- 压缩代码--JS、CSS、ES
- 使用Tree Shaking剔除JS死代码
优化输出质量--加速网络请求
- 使用CSN加速静态资源加载
- 网页的静态资源上传到CDN服务上,访问资源时,使用CDN服务提供的URL。
- 多页面应用提取页面键公共代码,利用缓存
- 分割代码,按需加载