初级分析:使用webpack内置的stats
stats:构建统计信息
package.json中使用stats
"scripts": {
"build:stats":"webpack --env production --json > stats.json"
}
复制代码
指定输出的json对象,输出一个json文件
Node.js 中使用
const webpack = require('webpack')
const config = require('./webpack.config.js')('production')
webacpk(config, (err, stats) => {
if(err) {
return console.error(err);
}
if(stats.hasErrors()) {
return console.log(stats.toString("errors-only"))
}
console.log(stats);
})
复制代码
缺点:颗粒度太粗,看不出问题所在。
速度分析:使用speed-measure-webpack-plugin
const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMesurePlugin();
const webpackConfig = smp.wrap({
plugins: [
new MyPlugin();
new MyOtherplugin()
]
})
复制代码
速度分析插件作用
- 分析整个打包总耗时
- 每个插件和loader的耗时情况
体积分析:使用webpack-bundle-analyzer分析体积
const {BundleAnalyzerPlugin} =require('webpack-bundle-analyzer')
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
复制代码
构建完成后会在8888端口展开大小
可以分析哪些问题?
- 依赖的第三方模块文件大小
- 业务里面的组件代码大小
多进程多实例构建
使用thread-loader解析资源
原理:每次webpack解析一个模块,thread-loader会将他及它的依赖分配给worker线程中
use:[
{
loader:'thread-loader',
options: {
workers: 3
}
}]
复制代码
多进程实例并行压缩
- 方法一:使用parallel-uglify-plugin插件
const ParalleUglifyPlugin = require('parallel-uglify-plugin')
module.exports = {
plugins: [
new ParalleUglifyPlugin({
uglifyJs:{
output: {
beautify:false,
comments:false,
},
compress:{
warnings: false,
drop_console:true,
collapse_vars:true,
reduce_vars:true
}
}
})
]
}
复制代码
- 方法二:uglifyjs-webpack-plugin开启parallel参数
plugins: [
new UglifyJsPlugin({
uglifyOptions:{},
parallel:true
})
]
复制代码
- 方法三(推荐):terser-webpack-plugin开启parallel参数
module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
parrallel:4
})
]
}
}
复制代码
进一步分包:预编译资源模块
思路:将react, react-dom, redux, react-redux基础包和业务基础打包成一个文件。
方法:创建一个单独的配置文件,一般命名为webpack.dll.js,使用DLLPlugin进行分包,DllReferencePlugin对manifest.json引用。
const path = require('path')
const webpack = requrie('webpack')
module.exports = {
context: process.cwd(),
resolve:{
extensions:['js', 'jsx', '.json', '.less', '.css'],
modules:[__dirname, 'node_modules']
},
entry: {
library: [
'react',
'react-dom',
'redux',
'react-redux']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, './build/library'),
library: '[name]'
},
plugins: [
new webpack.Dllplygin({
name: '[name]',
path: './build/library/[name].json'
})
]
}
复制代码
在webpack.config.js引入
module.exports = {
plugins: [
new webpack.DllReferencePlugin({
mainfest:require('./build/library/mainfest.json')
})
]
}
复制代码
充分利用缓存提升二次构建速度
缓存思路:
- babel-loader开启缓存
- terser-webpack-plugin开启缓存
- 使用cache-loader或者hard-source-webpack-plugin
缩小构建目标
目的:尽可能的少构建模块
比如babel-laoder不解析node_modules
module.exports = {
rules: {
test: /\\.js$/,
loader: 'babel-loader',
exclude: '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'],
mainFilelds:['main'],
}
}
复制代码
使用webpack进行图片压缩
要求: 基于Node库的imagemin或者tinypngAPI
使用: 配置image-webpack-loader
return {
test: /\\.(png|svg|jpg|gif)$/,
use: [{
loader:'file-loader'
options:{
name: `${filename}img/[name]${hash}.[ext]`
}
},{
loader:'image-webpack-loader',
options: {
mojpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
} ,
pngquant: {
quality: '65-90',
speed: 4
}
}
}]
}
复制代码
imagemin的优点点分析
- 有很多定制选项
- 可以引入更多第三方优化插件,例如pngquant
- 可以处理多种图片格式
使用TreeShaking擦除无用的CSS
无用的CSS如何删除掉?
- PurifyCSS:遍历代码,识别已经用到的CSS class
- uncss:HTML需要通过jsdom加载, 所有的样式通过PostCSS解析,通过document.querySelector来识别在html文件里面不存在的选择器。
在webpack中如何使用PurifyCSS?
- 使用purgecss-webpack-webpack-plugin(www.npmjs.com/package/pur…)
- 和mini-css-extract-plugin配合使用
使用动态Polyfill服务
- babel-polyfill(React16官方推荐)
- polyfill-service(社区维护)
Polyfill Service原理
识别User Agent,下发不同的Polyfill
体积优化策略总结
- Scope Hoisting
- scope hoisting 后会把需要导入的文件直接移入导入者顶部,这就是所谓的 hoisting,需要添加 ModuleConcatenationPlugin(模块关联)插件
- Tree-shaking
- 公共资源分离
- 图片压缩
- 动态Polyfill
原文链接: https://juejin.cn/post/6844904136622751758
来源:oschina
链接:https://my.oschina.net/u/4412439/blog/4948721