Webpack 構建優化總結
初級分析:使用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
「其他文章」
- Webpack 構建優化總結
- 中國上市:最便宜的法拉利敞篷超跑來了
- 給自己打工,從0到1,如何讓自己成為一個品牌
- 親歷者說 | 完整記錄一年多考拉海購的雲原生之路
- 資料分析框架和任務拆解?看看大神怎麼做!
- 你為什麼從來都不解除安裝微信?
- 基於業務和平臺理解數字營銷概念
- 工作之後,如何構建知識體系?
- 遠端桌面超出最大連線數的解決方法
- Linux伺服器作業系統快速刪除大量/大檔案
- mall在Windows環境下的部署
- 為什麼選擇Playwright?
- spring中構造方法、@PostConstruct、@Autowired、@Value的載入順序
- XDOJ期末考試題
- 如何做到讓別人看完你的述職報告,覺得晉升非你莫屬?
- 第5章 第2節 陣列
- HTML 文字格式化
- 推薦 9 個愛不釋手的 JSON 工具
- UWA學堂|測試模組知識Tree
- TLS/SSL 協議-非對稱加密(RSA)原理