代碼優(yōu)化到?成產(chǎn)物階段的效率提升,這?階段的優(yōu)化可以分為兩個不同的?向:
- 針對某些任務,使?效率更?的?具或配置項菩浙,從?提升當前任務的?作效率迎罗。
- 提升特定任務的優(yōu)化效果睬愤,以減少傳遞給下?任務的數(shù)據(jù)量,從?提升后續(xù)環(huán)節(jié)的?作效率纹安。
以提升當前任務?作效率為?標的?案
?般在項?的優(yōu)化階段尤辱,主要耗時的任務有兩個:?個是?成 ChunkAssets,即根據(jù) Chunk 信息?成 Chunk 的產(chǎn)物代碼厢岂;另?個是優(yōu)化 Assets光督,即壓縮 Chunk 產(chǎn)物代碼。
-
?向 JS 的壓縮?具
Webpack 4 中內(nèi)置了 TerserWebpackPlugin 作為默認的 JS 壓縮?具塔粒,之前的版本則需要在項?配置中單獨引?结借,早期主要使?的是 UglifyJSWebpackPlugin。這兩個 Webpack 插件內(nèi)部的壓縮功能分別基于 Terser 和 UglifyJS卒茬。在作為 Webpack 插件的 TerserWebpackPlugin 中映跟,對執(zhí)?效率產(chǎn)?影響的配置主要分為 3 個??:
- Cache 選項:默認開啟,使?緩存能夠極?程度上提升再次構(gòu)建時的?作效率扬虚。
- Parallel 選項:默認開啟努隙,并發(fā)選項在?多數(shù)情況下能夠提升該插件的?作效率,但具體提升的程度則因項??異辜昵。在?型項?中荸镊,多進程通信的額外消耗可能會抵消其帶來的益處。
-
terserOptions 選項:即 Terser ?具中的 minify 選項集合堪置。這些選項是對具體壓縮處理過程產(chǎn)?影響的配置項躬存。
a. compress 參數(shù)的作?是執(zhí)?特定的壓縮策略,例如省略變量賦值的語句舀锨,從?將變量的值直接替換到引?變量的位置上岭洲,減?代碼體積。?當 compress 參數(shù)為 false 時坎匿,這類壓縮策略不再?效盾剩。
b. mangle 參數(shù)的作?是對源代碼中的變量與函數(shù)名稱進?壓縮雷激。
c. 當 compress 參數(shù)為 false 時,壓縮階段的效率有明顯提升告私,同時對壓縮的質(zhì)量影響較?屎暇。在需要對壓縮階段的效率進?優(yōu)化的情況下,可以優(yōu)先選擇設置該參數(shù)驻粟。
-
?向 CSS 的壓縮?具
- OptimizeCSSAssetsPlugin(在 Create-React-App 中使?)
- OptimizeCSSNanoPlugin(在 VUE-CLI 中使?)
- CSSMinimizerWebpackPlugin(2020 年 Webpack 社區(qū)新發(fā)布的 CSS 壓縮插件)根悼。
這三個插件在壓縮 CSS 代碼功能??,都默認基于 cssnano 實現(xiàn)蜀撑,因此在壓縮質(zhì)量??沒有什么差別挤巡。
在壓縮效率??,?先值得?提的是最新發(fā)布的 CSSMinimizerWebpackPlugin酷麦,它?持緩存和多進程玄柏,這是另外兩個?具不具備的。
以提升后續(xù)環(huán)節(jié)?作效率為?標的?案
-
Split Chunks(分包)
指在 Chunk ?成之后贴铜,將原先以??點來劃分的 Chunks 根據(jù)?定的規(guī)則(例如異步引?或分離公共依賴等原則)粪摘,分離出? Chunk 的過程。Webpack 4 中內(nèi)置的 SplitChunksPlugin绍坝,該插件在 production 模式下默認啟?徘意。其默認的分包規(guī)則為 chunks: 'async',作?是分離動態(tài)引?的模塊 (import('...'))轩褐,在處理動態(tài)引?的模塊時能夠?動分離其中的公共依賴椎咧。設置為 chunks: 'all',則能夠?qū)⑺械囊蕾嚽闆r都進?分包處理把介,從?減少了重復引?相同模塊代碼的情況勤讽。
SplitChunksPlugin 的?作階段是在 optimizeChunks 階段(Webpack 4 中是在 optimizeChunksAdvanced,在 Webpack 5 中去掉了 basic 和 advanced拗踢,合并為 optimizeChunks)脚牍,?壓縮代碼是在 optimizeChunkAssets 階段,從?起到提升后續(xù)環(huán)節(jié)?作效率的作?巢墅。
-
Tree Shaking(搖樹)
指在構(gòu)建打包過程中诸狭,移除那些引?但未被使?的?效代碼(Deadcode elimination)。這種優(yōu)化?段最早應?于在 Rollup ?具中君纫,?在 Webpack 2 之后的版本中驯遇, Webpack 開始內(nèi)置這?功能。
引?不同的依賴包(lodash vs lodash-es)蓄髓、不同的引??式叉庐,以及是否使? babel 等,都會對 Tree Shaking 的效果產(chǎn)?影響ES6 模塊: ?先会喝,只有 ES6 類型的模塊才能進? Tree Shaking陡叠。因為 ES6 模塊的依賴關系是確定的玩郊,因此可以進?不依賴運?時的靜態(tài)分析。? CommonJS 類型的模塊則不能匾竿,需要依賴第三?提供的插件(例如 babel-plugin-lodash 等)才能實現(xiàn)動態(tài)刪除?效代碼瓦宜。
引??式:以 default ?式引?的模塊蔚万,?法被 Tree Shaking岭妖;?引?單個導出對象的?式,?論是使? import * as xxx 的語法反璃,還是 import { xxx } 的語法昵慌,都可以進? Tree Shaking。
sideEffects:在 Webpack 4 中淮蜈,會根據(jù)依賴模塊 package.json 中的 sideEffects 屬性來確認對應的依賴包代碼是否會產(chǎn)?副作?斋攀。只有 sideEffects 為 false 的依賴包(或不在 sideEffects 對應數(shù)組中的?件),才可以實現(xiàn)安全移除未使?代碼的功能梧田。
Babel:在 Babel 7 之前的 babel-preset-env 中淳蔼,modules 的默認選項為 'commonjs',因此在使? babel 處理模塊時裁眯,即使模塊本身是 ES6 ?格的鹉梨,也會在轉(zhuǎn)換過程中,因為被轉(zhuǎn)換?導致?法在后續(xù)優(yōu)化階段應? Tree Shaking穿稳。?在 Babel 7 之后的 @babel/preset-env 中存皂,modules 選項默認為 ‘a(chǎn)uto’,它的含義是對 ES6 ?格的模塊不做轉(zhuǎn)換(等同于 modules: false)逢艘,?將其他類型的模塊默認轉(zhuǎn)換為 CommonJS ?格旦袋。