1、使用高版本
的 Webpack 和 Node.js
2、多進程/多實例構建
:HappyPack(不維護了)、thread-loader
3、壓縮代碼
- webpack-paralle-uglify-plugin
- uglifyjs-webpack-plugin 開啟 parallel 參數 (不支持ES6)
- terser-webpack-plugin 開啟 parallel 參數
- 多進程並行壓縮
- 通過 mini-css-extract-plugin 提取 Chunk 中的 CSS 代碼到單獨文件,通過 css-loader 的 minimize 選項開啟 cssnano 壓縮 CSS。
4、圖片壓縮
- 使用基於 Node 庫的 imagemin (很多定制選項、可以處理多種圖片格式)
- 配置 image-webpack-loader
5、縮小打包作用域
- exclude/include (確定 loader 規則范圍)
- resolve.modules 指明第三方模塊的絕對路徑 (減少不必要的查找)
- resolve.mainFields 只采用 main 字段作為入口文件描述字段 (減少搜索步驟,需要考慮到所有運行時依賴的第三方模塊的入口文件描述字段)
- resolve.extensions 盡可能減少后綴嘗試的可能性
- noParse 對完全不需要解析的庫進行忽略 (不去解析但仍會打包到 bundle 中,注意被忽略掉的文件里不應該包含 import、require、define 等模塊化語句)
- IgnorePlugin (完全排除模塊)
- 合理使用alias
6、提取頁面公共資源
- 使用 html-webpack-externals-plugin,將基礎包通過 CDN 引入,不打入 bundle 中
- 使用 SplitChunksPlugin 進行(公共腳本、基礎包、頁面公共文件)分離(Webpack4內置) ,替代了 CommonsChunkPlugin 插件
- 基礎包分離:
7、DLL分包,避免反復編譯浪費時間
- 使用 DllPlugin 進行分包,使用 DllReferencePlugin(索引鏈接) 對 manifest.json 引用,讓一些基本不會改動的代碼先打包成靜態資源,避免反復編譯浪費時間。
- HashedModuleIdsPlugin 可以解決模塊數字id問題
8、充分利用緩存提升二次構建速度
- babel-loader 開啟緩存
- terser-webpack-plugin 開啟緩存
- 使用 cache-loader 或者 hard-source-webpack-plugin
9、Tree shaking
- purgecss-webpack-plugin 和 mini-css-extract-plugin配合使用(建議)
- 打包過程中檢測工程中沒有引用過的模塊並進行標記,在資源壓縮時將它們從最終的bundle中去掉(只能對ES6 Modlue生效) 開發中盡可能使用ES6 Module的模塊,提高tree shaking效率
- 禁用 babel-loader 的模塊依賴解析,否則 Webpack 接收到的就都是轉換過的 CommonJS 形式的模塊,無法進行 tree-shaking
- 使用 PurifyCSS(不在維護) 或者 uncss 去除無用 CSS 代碼
10、Scope hoisting
- 構建后的代碼會存在大量閉包,造成體積增大,運行代碼時創建的函數作用域變多,內存開銷變大。Scope hoisting 將所有模塊的代碼按照引用順序放在一個函數作用域里,然后適當的重命名一些變量以防止變量名沖突
- 必須是ES6的語法,因為有很多第三方庫仍采用 CommonJS 語法,為了充分發揮 Scope hoisting 的作用,需要配置 mainFields 對第三方模塊優先采用 jsnext:main 中指向的ES6模塊化語法
更多優化請參考官網-構建性能:https://www.webpackjs.com/guides/build-performance