webpack
构建速度和体积优化策略
初级分析:使用webpack
内置的stats
stats
:构建的统计信息
package.json
中使用stats
"scripts":{
"build:stats":"webpack --env production --json > stats.json"
}
速度分析:使用speed-measure-webpack-plugin
代码示例
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
const webpackConfig = smp.wrap({
plugin:[
new MyPlugin(),
new MyOtherPlugin()
]
})
可以看到每个loader
和插件执行耗时
npm i --save-dev speed-measure-webpack-plugin
webpack-bundle-analyzer
分析体积
代码示例
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
plugins:{
new BundleAnalyzerPlugin()
}
}
可以分析那些问题
依赖的第三方模块文件大小
业务里面的组件代码大小
使用webpack4
:优化原因
v8
带来的优化(for of
替代 forEach
Map Set
替代 Object
includes
替代 indexOf
)
默认使用更快的 md4 hash
算法
webpack AST
可以直接从loader
传递给AST
,减少解析时间
使用字符串方法替代正则表达式
多进程 / 多实例构建:资源并行解析可选方案
thread-loader
- 可选方案
parallel-webpack
HappyPack
多进程 / 多实例 : 并行压缩
方法一:使用parallel-uglify-webpack
插件
const ParallelUglifyWebpack = require('parallel-uglify-webpack')
module.exports = {
plugins : [
new ParallelUglifyWebpack({
uglifyJS :{
output:{
beaytify:false,
comments:false,
},
compress :{
warnings :false,
drop_console:true,
collapse_vars :true,
reduce_vars:true
}
}
})
]
}
分包:设置Externals
思路:将react
、reeact-dom
基础包通过cdn
引入,不打入bundle
中
方法:使用html-webpack-externals-plugin
进一步分包:预编译资源模块
思路:将react
、react-dom
、redux
、react-redux
等基础包和业务基础包打包成一个文件
方法:使用DLLPlugin
进行分包,DllReferencePlugin
对manifest.json
引用
使用DllPlugin
进行分包
使用DllReferencePlugin
引用manifest.json
在webpack.config.js
引入
module.exports = {
plugins:[
new webpack.DllRederencePlugin({
manifest: require('./build/library/manifest.json')
})
]
}
缓存
目的:提升二次构建速度
缓存思路
babel-loader
开启缓存terser-webpack-plugin
开启缓存- 使用
cache-loader
或者hard-source-webpack-plugin
缩小构建目标
目的:尽可能得少构建模块
比如babel-loader
不解析node_modules
module.exports = {
rules :{
test:/\.js$/,
loader:'happypack/loader',
excluder:'node_modules'
}
}
减少文件搜索范围
优化 resolve.modules
配置(减少模块搜索层级)
优化resolve.mainFields
配置
优化resolve.extensions
配置
合理使用alias
module.exports = {
resolve :{
alias:{
react:path.resolve(__dirname,'./node_modules/react/dist/react.min.js'),
},
modules:[path.resolve(__dirname,'node_modules')],
extensions:['.js'],
mainFields:['main']
}
}
图片压缩
要求:基于Node
库的imagemin
或者tinypng API
使用:配置image-webpack-loader
Imagemin
的优点分析
有很多定制选项
可以引入更多第三方优化插件,例如pngquant
可以处理多种图片格式
使用TreeShaking
擦除无用的的css
PurifyCSS
:遍历代码,识别已经用到的CSS class
uncss
:HTML
需要通过jsdom
加载,所有的样式通过PostCSS
解析,通过documnet.querySelector
来识别在html
文件里面不存在的选择器
在webpack
中如何使用PurifyCSS
使用 purgecss-webpack-plugin
以及和min-css-extract-pugin
配合使用
构建体积优化:动态Polyfill
polyfill-service
- 优点:只给用户返回需要的
Polyfill
,社区维护 - 缺点:部分浏览器
UA
可能无法识别(但是可以降级返回所需全部Polyfill
)
Polyfill Service
原理
识别User Agent
,下发不同的Polyfill
性能优化策略
渲染优化
- 首页、列表页、详情页采用
SSR
或者Native
渲染 - 个人中心页预渲染
弱网优化
- 使用离线包,
PWA
等离线缓存技术
Webview
优化
- 打开
Webview
的同时并行的加载页面数据