說到優(yōu)化圃酵,首先肯定要通過一些分析工具找出項目存在的問題,然后針對問題來做對應的優(yōu)化嘿歌。
webpack優(yōu)化分為兩個方向:
1.構建速度層面優(yōu)化
安裝打包耗時分析插件:
npm install --save-dev speed-measure-webpack-plugin
使用方法:
// 導入速度分析插件
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
// 實例化插件
const smp = new SpeedMeasurePlugin();
//調用wrap方法掸掏,傳入webpack配置對象
smp.wrap({
plugins: []
})
2.代碼輸出質量優(yōu)化
安裝打包體積分析插件:
npm install --save-dev webpack-bundle-analyzer
// 導入體積分析插件
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
plugins: [
// 實例化體積分析插件
new BundleAnalyzerPlugin()
]
//執(zhí)行打包命令之后,本地http://127.0.0.1:8888/頁面可查看打包后體積分布
構建速度層面優(yōu)化:
1.縮小打包作用域
1.1 test/exclude/include 確定loader規(guī)則范圍
1.2 resolve.modules 默認值為['node_modules'],含義是先去當前目錄的node_modules下去找模塊宙帝,沒有找到就去上一級../node_modules中找丧凤,當?shù)谌侥K的路徑確定時,可以指定其絕對路徑步脓,以減少尋找愿待。
module.exports={
resolve:{
modules:[path.resolve(__dirname,'node_modules')]
}
}
1.3 resolve.mainFields
當webpack的target屬性設置為 webworker, web 或者沒有指定,默認值為:
mainFields: ["browser", "module", "main"]
對于其他任意的 target(包括 node)靴患,默認值為:
mainFields: ["module", "main"]
為了減少搜索步驟仍侥,如果你使用到的第三方模塊的入口文件描述字段都是main時,可以把mainFields設為['main']
1.4 alias 配置別名
通過配置別名來將原導入路徑映射成一個新的導入路徑,例如一些龐大的第三方模塊鸳君,可以用別名指定其公共文件农渊,從而跳過耗時的遞歸解析操作。
1.5 resolve.extensions 盡可能減少后綴嘗試的可能性
在源碼的導入時或颊,也盡可能帶上后綴砸紊,避免尋找過程
1.6 noParse 對完全不需要解析的庫進行忽略
防止 webpack 解析那些任何與給定正則表達式相匹配的文件。忽略的文件中不應該含有 import, require, define 的調用囱挑,或任何其他導入機制醉顽。忽略大型的 library 可以提高構建性能
1.7 預編譯資源模塊
DllPlugin結合DllReferencePlugin
或者:
hard-source-webpack-plugin ,配置簡單,推薦使用
把復用性較高的第三方模塊打包到動態(tài)鏈接庫中看铆,在不升級這些庫的情況下,動態(tài)庫不需要重新打包盛末,每次構建只重新打包業(yè)務代碼
2.多進程構建
2.1 thread-loader插件
webpack 是單線程模型的弹惦,所以webpack 需要一個一個地處理任務,不能同時處理多個任務悄但。
thread-loader會將你的 loader 放置在一個 worker 池里面運行棠隐,以達到多線程構建。
2.2 多進程并行壓縮代碼
webpack默認提供了UglifyJS插件來壓縮JS代碼檐嚣,但是它使用的是單線程壓縮代碼助泽,也就是說多個js文件需要被壓縮啰扛,它需要一個個文件進行壓縮
目前有三種主流的多進程壓縮方案:
parallel-uglify-plugin
uglifyjs-webpack-plugin
terser-webpack-plugin
這些插件能開啟多個子進程,把對多個文件壓縮的工作分別給多個子進程去完成嗡贺,但是每個子進程還是通過UglifyJS去壓縮代碼隐解。無非就是變成了并行處理該壓縮了,并行處理多個子任務诫睬,效率會更加的提高
3.充分利用緩存
3.1 cache-loader
代碼輸出質量優(yōu)化
1. 用 webpack 實現(xiàn) CDN 的接入
靜態(tài)資源的導入 URL 需要變成指向 CDN 服務的絕對路徑的 URL 而不是相對于 HTML 文件的 URL煞茫。
靜態(tài)資源的文件名稱需要帶上有文件內容算出來的 Hash 值,以防止被緩存摄凡。
不同類型的資源放到不同域名的 CDN 服務上去续徽,以防止資源的并行加載被阻塞。
web-webpack-plugin 單頁面應用生成 HTML 文件
extract-text-webpack-plugin
2. 多入口項目提取公共代碼
SplitChunksPlugin 進行(公共腳本亲澡、基礎包钦扭、頁面公共文件)分離(Webpack4內置)
3. 按需加載
webpack支持兩種動態(tài)代碼拆分技術:
- import()語法,用import引入的模塊以及其子模塊會被分割打包成一個獨立的chunk
- 傳統(tǒng)的require.ensure
4. 使用tree shaking
tree shaking是一個術語,通常用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)床绪。它依賴于 ES2015 模塊系統(tǒng)中的靜態(tài)結構特性客情,例如 import和 export
使用:
- 使用 ES2015 模塊語法(即 import 和 export)。
- 導入模塊副作用的設置会涎,在項目 package.json 文件中裹匙,添加一個 sideEffects入口,或者在module.rules配置選項中設置 sideEffects末秃。
- 引入一個能夠刪除未引用代碼(dead code)的壓縮工具(minifier)(例如 UglifyJSPlugin)概页。
5. 動態(tài) Polyfill 服務
babel-polyfill由于是一次性全部導入整個polyfill,所以用起來很方便练慕,但與此同時也帶來了一個大問題:文件很大
動態(tài) polyfill 指的是根據(jù)不同的瀏覽器惰匙,動態(tài)載入需要的 polyfill。 Polyfill.io 通過嘗試使用 polyfill 重新創(chuàng)建缺少的功能铃将,可以更輕松地支持不同的瀏覽器项鬼,并且可以大幅度的減少構建體積。
使用方法:在 index.html 中引入如下 script 標簽
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js"></script>
6. 啟用Scope Hoisting
Scope hoisting(作用域提升),即讓webpack 會把引入的 js 文件“提升到”它的引入者頂部劲阎。
Scope Hoisting 可以讓 Webpack 打包出來的代碼文件更小绘盟、運行的更快。
Webpack 內置的功能悯仙,只需要配置一個插件
plugins: [new webpack.optimize.ModuleConcatenationPlugin()]