Webpack優(yōu)化
打包速度:
按需引入
壓縮代碼
每個路由頁面單獨打包使用時再去下載
性能優(yōu)化:
v-if代替v-show
公共組件提取
異步組件
路由懶加載
使用緩存減少http請求
- 如何提?webpack的打包速度?
(1)優(yōu)化 Loader
對于 Loader 來說牲距,影響打包效率首當其沖必屬 Babel 了蔓肯。因為 Babel 會將代碼轉(zhuǎn)為字符串生成 AST绍昂,然后對 AST 繼續(xù)進行轉(zhuǎn)變最后再生成新的代碼摄乒,項目越大从媚,轉(zhuǎn)換代碼越多幅聘,效率就越低。當然了沙峻,這是可以優(yōu)化的。
首先我們優(yōu)化 Loader 的文件搜索范圍
module.exports = {
module: {
rules: [
{
// js 文件才使用 babel
test: /.js/,
include: [resolve('src')],
exclude: /node_modules/,
// id 后面的內(nèi)容對應下面
loader: 'happypack/loader?id=happybabel'
}
]
},
plugins: [
new HappyPack({
id: 'happybabel',
loaders: ['babel-loader?cacheDirectory'],
// 開啟 4 個線程
threads: 4
})
]
復制代碼
(3)DllPlugin
DllPlugin 可以將特定的類庫提前打包然后引入。這種方式可以極大的減少打包類庫的次數(shù)厚满,只有當類庫更新版本才有需要重新打包府瞄,并且也實現(xiàn)了將公共代碼抽離成單獨文件的優(yōu)化方案。DllPlugin的使用方法如下:
// 單獨配置在一個文件中
// webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
// 想統(tǒng)一打包的類庫
vendor: ['react']
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].dll.js',
library: '[name]-[hash]'
},
plugins: [
new webpack.DllPlugin({
// name 必須和 output.library 一致
name: '[name]-[hash]',
// 該屬性需要與 DllReferencePlugin 中一致
context: __dirname,
path: path.join(__dirname, 'dist', '[name]-manifest.json')
})
]
}
復制代碼
然后需要執(zhí)行這個配置文件生成依賴文件痰滋,接下來需要使用 DllReferencePlugin 將依賴文件引入項目中
// webpack.conf.js
module.exports = {
// ...省略其他配置
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
// manifest 就是之前打包出來的 json 文件
manifest: require('./dist/vendor-manifest.json'),
})
]
}
復制代碼
(4)代碼壓縮
在 Webpack3 中摘能,一般使用 UglifyJS 來壓縮代碼续崖,但是這個是單線程運行的敲街,為了加快效率,可以使用 webpack-parallel-uglify-plugin 來并行運行 UglifyJS严望,從而提高效率多艇。
在 Webpack4 中,不需要以上這些操作了像吻,只需要將 mode 設置為 production 就可以默認開啟以上功能峻黍。代碼壓縮也是我們必做的性能優(yōu)化方案复隆,當然我們不止可以壓縮 JS 代碼,還可以壓縮 HTML姆涩、CSS 代碼挽拂,并且在壓縮 JS 代碼的過程中,我們還可以通過配置實現(xiàn)比如刪除 console.log 這類代碼的功能骨饿。
(5)其他
可以通過一些小的優(yōu)化點來加快打包速度
resolve.extensions:用來表明文件后綴列表亏栈,默認查找順序是 ['.js', '.json'],如果你的導入文件沒有添加后綴就會按照這個順序查找文件宏赘。我們應該盡可能減少后綴列表長度绒北,然后將出現(xiàn)頻率高的后綴排在前面
resolve.alias:可以通過別名的方式來映射一個路徑,能讓 Webpack 更快找到路徑
module.noParse:如果你確定一個文件下沒有其他依賴察署,就可以使用該屬性讓 Webpack 不掃描該文件闷游,這種方式對于大型的類庫很有幫助
- 如何減少 Webpack 打包體積
(1)按需加載
在開發(fā) SPA 項目的時候,項目中都會存在很多路由頁面贴汪。如果將這些頁面全部打包進一個 JS 文件的話脐往,雖然將多個請求合并了,但是同樣也加載了很多并不需要的代碼扳埂,耗費了更長的時間钙勃。那么為了首頁能更快地呈現(xiàn)給用戶,希望首頁能加載的文件體積越小越好聂喇,這時候就可以使用按需加載辖源,將每個路由頁面單獨打包為一個文件。當然不僅僅路由可以按需加載希太,對于 loadash 這種大型類庫同樣可以使用這個功能克饶。
按需加載的代碼實現(xiàn)這里就不詳細展開了,因為鑒于用的框架不同誊辉,實現(xiàn)起來都是不一樣的矾湃。當然了,雖然他們的用法可能不同堕澄,但是底層的機制都是一樣的邀跃。都是當使用的時候再去下載對應文件,返回一個 Promise蛙紫,當 Promise 成功以后去執(zhí)行回調(diào)拍屑。
(2)Scope Hoisting
Scope Hoisting 會分析出模塊之間的依賴關系,盡可能的把打包出來的模塊合并到一個函數(shù)中去坑傅。
比如希望打包兩個文件:
// test.js
export const a = 1
// index.js
import { a } from './test.js'
復制代碼
對于這種情況僵驰,打包出來的代碼會類似這樣:
[
/* 0 /
function (module, exports, require) {
//...
},
/ 1 /
function (module, exports, require) {
//...
}
]
復制代碼
但是如果使用 Scope Hoisting ,代碼就會盡可能的合并到一個函數(shù)中去,也就變成了這樣的類似代碼:
[
/ 0 */
function (module, exports, require) {
//...
}
]
復制代碼
這樣的打包方式生成的代碼明顯比之前的少多了蒜茴。如果在 Webpack4 中你希望開啟這個功能星爪,只需要啟用 optimization.concatenateModules 就可以了:
module.exports = {
optimization: {
concatenateModules: true
}
}
復制代碼
(3)Tree Shaking
Tree Shaking 可以實現(xiàn)刪除項目中未被引用的代碼,比如:
// test.js
export const a = 1
export const b = 2
// index.js
import { a } from './test.js'
復制代碼
對于以上情況粉私,test 文件中的變量 b 如果沒有在項目中使用到的話顽腾,就不會被打包到文件中。
如果使用 Webpack 4 的話诺核,開啟生產(chǎn)環(huán)境就會自動啟動這個優(yōu)化功能崔泵。 - 如何?webpack來優(yōu)化前端性能?
?webpack優(yōu)化前端性能是指優(yōu)化webpack的輸出結(jié)果猪瞬,讓打包的最終結(jié)果在瀏覽器運?快速?效憎瘸。
壓縮代碼:刪除多余的代碼、注釋陈瘦、簡化代碼的寫法等等?式幌甘。可以利?webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 來壓縮JS?件痊项, 利? cssnano (css-loader?minimize)來壓縮css
利?CDN加速: 在構(gòu)建過程中锅风,將引?的靜態(tài)資源路徑修改為CDN上對應的路徑“叭可以利?webpack對于 output 參數(shù)和各loader的 publicPath 參數(shù)來修改資源路徑
Tree Shaking: 將代碼中永遠不會?到的?段刪除掉皱埠。可以通過在啟動webpack時追加參數(shù) --optimize-minimize 來實現(xiàn)
Code Splitting: 將代碼按路由維度或者組件分塊(chunk),這樣做到按需加載,同時可以充分利?瀏覽器緩存
提取公共第三?庫: SplitChunksPlugin插件來進?公共模塊抽取,利?瀏覽器緩存可以?期緩存這些?需頻繁變動的公共代碼
- 如何提?webpack的構(gòu)建速度咖驮?
多??情況下边器,使? CommonsChunkPlugin 來提取公共代碼
通過 externals 配置來提取常?庫
利? DllPlugin 和 DllReferencePlugin 預編譯資源模塊 通過 DllPlugin 來對那些我們引?但是絕對不會修改的npm包來進?預編譯,再通過 DllReferencePlugin 將預編譯的模塊加載進來托修。
使? Happypack 實現(xiàn)多線程加速編譯
使? webpack-uglify-parallel 來提升 uglifyPlugin 的壓縮速度忘巧。 原理上 webpack-uglify-parallel 采?了多核并?壓縮來提升壓縮速度
使? Tree-shaking 和 Scope Hoisting 來剔除多余代碼
作者:CUGGZ
鏈接:https://juejin.cn/post/6941278592215515143
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)睦刃,非商業(yè)轉(zhuǎn)載請注明出處砚嘴。