Vue多頁面配置打包性能優(yōu)化方式(解決加載包太大加載慢問題)
通常我們使用vue-cli開發(fā)多頁面的時候,不知道您是否注意一個問題沒有?
默認(rèn)情況:webpack 會將多入口通用的組件庫等,打包一個 vendor 的 chunk js 中
現(xiàn)在假設(shè)有兩個頁面:
入口 admin 使用到了element-ui組件庫和echarts圖表庫,入口 index 使用了iview的組件庫
一、問題描述及解決方案
1. 多入口存在的問題
那么這樣就會存在問題:
- 打出來的chunk-vendor.xxxx.js會包含element-ui和echarts和iview組件庫,所以 js 體積會非常大
- chunk-vendor.xxxx.js默認(rèn)是所有node_modules下面的庫集合
- index 入口只是使用了 iview,由于需要加載chunk-vendor.xxxx.js,所以造成了不必要的加載
- admin 入口 同上 會額外引入 iview
2. 我的預(yù)期效果
那么針對以上的問題,我們預(yù)期應(yīng)該是怎樣的呢?
- index 入口和 admin 各自單獨打包,按需引入各自的庫
- index 和 admin 公用的庫 只打包一次
3. 可行方案
針對以上的需求,我探索出了一下兩種方案:
- 刪除默認(rèn) splitChunk 配置,打公共 chunks,單獨分離各自的 ui 庫(做減法)
- 刪除默認(rèn) splitChunk 配置,抽離公共資源(做加法)
二、方案一:打公共 chunks,單獨分離各自的ui庫
方案 1: 刪除默認(rèn) splitChunk 配置,打公共 chunks,單獨分離各自的 ui 庫
刪除默認(rèn) splitChunk 配置是了取消 webpack 的默認(rèn)配置,因為 webpack 默認(rèn)的配置是將node_modules下的所用到的庫打包成一個chunk-vendor.xxxx.js。
主要分成三步:
- 第一步: 刪除默認(rèn) splitChunk 的配置
- 第二步: 單獨配出 splitChunk
- 第三部: 為多入口,各自單獨配置 chunks
詳細(xì)配置如下:
let pages = { ? index: { ? ? entry: "src/main.js", ? ? template: "public/index.html", ? ? // 特別注意:由于各個入口單獨分離了chunk之后,需要將對于的chunk名顯示的列出 ? ? chunks: [ ? ? ? "index", //注意:這個是頁面名稱的chunk,下面的chunk名稱需要對呀splitChunk對應(yīng)的名稱 ? ? ? "chunk-vendors", //這是node_modules下的chunk ? ? ? "chunk-common", //這是admin和Index入口公用的chunk ? ? ? "chunk-iview" //index的單獨chunk ? ? ] ? }, ? admin: { ? ? entry: "src/admin.js", ? ? template: "public/admin.html", ? ? // 特別注意:由于各個入口單獨分離了chunk之后,需要將對于的chunk名顯示的列出 ? ? chunks: [ ? ? ? "admin", //注意:這個是頁面名稱的chunk,下面的chunk名稱需要對呀splitChunk對應(yīng)的名稱 ? ? ? "chunk-vendors", //這是node_modules下的chunk ? ? ? "chunk-common", //這是admin和Index入口公用的chunk ? ? ? "chunk-element-ui", //admin的單獨chunk ? ? ? "chunk-echarts", //admin的單獨chunk ? ? ? "zrender" //echarts用到了zrender ? ? ] ? } }; module.exports = { ? pages, ? publicPath: process.env.BASE_URL, ? outputDir: "dist", ? assetsDir: "assets", ? runtimeCompiler: true, ? productionSourceMap: false, ? parallel: true, ? css: { ? ? // 是否提取css 生產(chǎn)環(huán)境可以配置為 true ? ? extract: true ? }, ? chainWebpack: config => { ? ? if (process.env.NODE_ENV === "production") { ? ? ? // 刪除系統(tǒng)默認(rèn)的splitChunk ? ? ? config.optimization.delete("splitChunks"); ? ? } ? }, ? configureWebpack: config => { ? ? // 給輸出的js名稱添加hash ? ? config.output.filename = "[name].[hash].js"; ? ? config.output.chunkFilename = "[name].[hash].js"; ? ? ? config.optimization = { ? ? ? splitChunks: { ? ? ? ? cacheGroups: { ? ? ? ? ? // 抽離所有入口的公用資源為一個chunk ? ? ? ? ? common: { ? ? ? ? ? ? name: "chunk-common", ? ? ? ? ? ? chunks: "initial", ? ? ? ? ? ? minChunks: 2, ? ? ? ? ? ? maxInitialRequests: 5, ? ? ? ? ? ? minSize: 0, ? ? ? ? ? ? priority: 1, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? }, ? ? ? ? ? // 抽離node_modules下的庫為一個chunk ? ? ? ? ? vendors: { ? ? ? ? ? ? name: "chunk-vendors", ? ? ? ? ? ? test: /[\\/]node_modules[\\/]/, ? ? ? ? ? ? chunks: "initial", ? ? ? ? ? ? priority: 2, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? }, ? ? ? ? ? // 由于Index入口使用了iview,所以講iview單獨處理出來,這樣admin入口就不會使用此js ? ? ? ? ? iview: { ? ? ? ? ? ? name: "chunk-iview", ? ? ? ? ? ? test: /[\\/]node_modules[\\/]iview[\\/]/, ? ? ? ? ? ? chunks: "all", ? ? ? ? ? ? priority: 3, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? }, ? ? ? ? ? // 由于admin入口使用了element-ui,所以講element-ui單獨處理出來,這樣index入口就不會使用此js ? ? ? ? ? element: { ? ? ? ? ? ? name: "chunk-element-ui", ? ? ? ? ? ? test: /[\\/]node_modules[\\/]element-ui[\\/]/, ? ? ? ? ? ? ? ? ? //根據(jù)你實際的目錄情況來決定 /[\\/]node_modules[\\/]_?element-ui(.*)/, ? ? ? ? ? ? chunks: "all", ? ? ? ? ? ? priority: 3, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? }, ? ? ? ? ? // 由于admin入口使用了echarts,所以講echarts單獨處理出來,這樣index入口就不會使用此js ? ? ? ? ? echarts: { ? ? ? ? ? ? name: "chunk-echarts", ? ? ? ? ? ? test: /[\\/]node_modules[\\/](vue-)?echarts[\\/]/, ? ? ? ? ? ? chunks: "all", ? ? ? ? ? ? priority: 4, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? }, ? ? ? ? ? // 由于echarts使用了zrender庫,那么需要將其抽離出來,這樣就不會放在公共的chunk中 ? ? ? ? ? zrender: { ? ? ? ? ? ? name: "zrender", ? ? ? ? ? ? test: /[\\/]node_modules[\\/]zrender[\\/]/, ? ? ? ? ? ? chunks: "all", ? ? ? ? ? ? priority: 3, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? }; ? } };
三、方案二:刪除默認(rèn)splitChunk配置,抽離公共資源
其實告訴你,webpack如果是多入口的話,刪除默認(rèn)的 splitChunk 配置,多入口會單獨各自打包,但是公共資源不會抽取。
針對以上的情況我們可以通過以下三步達(dá)到優(yōu)化目的:
- 第一步:刪除默認(rèn)的 splitChunk
- 第二步:抽離公共的入口資源
- 第三部:為各自入口單獨配置 chunks
詳細(xì)配置如下
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") ? .BundleAnalyzerPlugin; let pages = { ? index: { ? ? entry: "src/main.js", ? ? template: "public/index.html", ? ? chunks: ["index", "chunk-common"] //分別是入口的名稱,也就是前面的key值,和公共chunk的名稱 ? }, ? admin: { ? ? entry: "src/admin.js", ? ? template: "public/admin.html", ? ? chunks: ["admin", "chunk-common"] //分別是入口的名稱,也就是前面的key值,和公共chunk的名稱 ? } }; module.exports = { ? pages, ? publicPath: process.env.BASE_URL, ? outputDir: "dist", ? assetsDir: "assets", ? runtimeCompiler: true, ? productionSourceMap: false, ? parallel: true, ? css: { ? ? // 是否提取css 生產(chǎn)環(huán)境可以配置為 true ? ? extract: true ? }, ? ? chainWebpack: config => { ? ? // 刪除默認(rèn)的splitChunk ? ? config.optimization.delete("splitChunks"); ? }, ? configureWebpack: config => { ? ? // js output config ? ? config.output.filename = "[name].[hash].js"; ? ? config.output.chunkFilename = "[name].[hash].js"; ? ? ? config.optimization = { ? ? ? splitChunks: { ? ? ? ? cacheGroups: { ? ? ? ? ? common: { ? ? ? ? ? ? //抽取所有入口頁面都需要的公共chunk ? ? ? ? ? ? name: "chunk-common", ? ? ? ? ? ? chunks: "initial", ? ? ? ? ? ? minChunks: 2, ? ? ? ? ? ? maxInitialRequests: 5, ? ? ? ? ? ? minSize: 0, ? ? ? ? ? ? priority: 1, ? ? ? ? ? ? reuseExistingChunk: true, ? ? ? ? ? ? enforce: true ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? }; ? } };
四、方案對比
方案一: 刪除默認(rèn) splitChunk 配置,打公共 chunks,單獨分離各自的 ui 庫(做減法)
優(yōu)點:不需要處理公共 chunk,單獨分離各自的 chunk 缺點:如果多入口使用的庫比較多,需要各自單獨的抽離
適用場景
適用于:多個入口頁面耦合性比較強的(也就是多入口使用的公共資源比較多的),只有少量組件庫不同
刪除默認(rèn) splitChunk 配置,抽離公共資源(做加法)
優(yōu)點:不需要單獨分離各自的 chunk,只需要處理公共 chunk 即可 缺點:如果多入口公共庫使用的比較多,抽離需要更加細(xì)致化
適用場景
適用于:多個入口頁面耦合性比較低的(也就是多入口使用的公共資源比較少,通常是多個入口沒有任何關(guān)系的)
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue為何棄用Ajax,選擇Axios?ajax與axios的區(qū)別?
ajax技術(shù)實現(xiàn)了局部數(shù)據(jù)的刷新,axios實現(xiàn)了對ajax的封裝;axios有的ajax都有,ajax有的axios不一定有。總結(jié)一句話就是axios是ajax,ajax不止axios。2023-01-01手把手教你如何將html模板資源轉(zhuǎn)為vuecli項目
Vue可以直接集成html,Vue就是前端框架,使用Vue做前端開發(fā)效率非常高,下面這篇文章主要給大家介紹了關(guān)于如何將html模板資源轉(zhuǎn)為vuecli項目的相關(guān)資料,需要的朋友可以參考下2023-04-04Vue+Element ui實現(xiàn)樹形控件右鍵菜單
這篇文章主要為大家詳細(xì)介紹了Vue+Element ui實現(xiàn)樹形控件右鍵菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07vue之帶參數(shù)跳轉(zhuǎn)打開新頁面、新窗口
這篇文章主要介紹了vue之帶參數(shù)跳轉(zhuǎn)打開新頁面、新窗口方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04