vue element-ui 優化打包 bundle js 大小
背景
最近開發的一個專案使用了 vue
+ element-ui
的技術棧,當然,還有其他的一些工具庫,比如 axios
。
說一下我的開發步驟,基礎結構是通過 [email protected]
建立的,手動的加入了 axios
vuex
, vue-router
是腳手架自帶的。
code split
1. 路由懶載入
使用 vue-router
的時候,如果按照預設配置,所有的路由都會被打包到一個 bundle.js
檔案中去(bundle 檔名一般是 app.js
)。
進入 router/index.js
檔案中,只需要將所有類似 import Home from '@/components/home';
const Home = () => import('@/components/home')
其餘部分不需要變。就能以最簡單的形式做到根據路由來劃分 webpack 打包的模組。這個時候 執行 npm run build
是就能看到多了很多小的 js 檔案, 並且app.js
檔案的體積也減小了。
附上程式碼示例:
import Vue from 'vue' import Router from 'vue-router' const AdminIndex = () => import('@/components/admin-index') const Home = () => import('@/components/home') Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'admin-index', component: AdminIndex }, { path: '/home', name: 'home', component: Home } ] })
2. 元件懶載入
跟路由懶載入的形式一樣,也是使用 () => import('xxx')
的形式。
如果對於一個容器元件中,import
很多個元件進來,使用元件懶載入,能夠繼續減小首次載入的檔案大小。示例程式碼:
<template> <div> <HomeHeader /> <SearchContainer /> <HomeFooter /> </div> </template> <script> import HomeHeader from "./home-header"; import HomeFooter from "./home-footer"; import SearchContainer from "./containers/search-container"; import LoadingComponent from "@/components/common/loading"; export default { name: "home", components: { HomeHeader, HomeFooter, SearchContainer, LoadingComponent } }; </script>
優化之前:
元件懶載入優化之後:
<template>
<div>
<HomeHeader />
<SearchContainer />
<HomeFooter />
</div>
</template>
<script>
const HomeHeader = () => import("./home-header");
const HomeFooter = () => import("./home-footer");
const SearchContainer = () => import("./containers/search-container");
export default {
name: "home",
components: {
HomeHeader,
HomeFooter,
SearchContainer
}
};
</script>
從檔案的個數中,不知道有沒有看出什麼?
app.js
是屬於 專案的公共部分的程式碼。而宣告一個 const HomeHeader = () => import("./home-header");
類似的元件,就會建立一個 n.js
檔案,達到了繼續拆分比較大的js包的目的。
所以其實只要你願意,可以一部分元件使用 const HomeHeader = () => import("./home-header");
另一部分元件使用 import HomeHeader from "./home-header";
。
不過總的來說,除非一個元件過於龐大了,在我開發過程中,才會想著用元件拆分的形式。每一個小元件都這樣拆分,最終得到很多很多個小的js檔案,反而是因為網路請求的原因,拖慢載入速度的。
3. webpack-bundle-analyzer
在做一個專案的一開始,其實我都沒有去考慮過效能優化、code split 的事情,只有當邏輯越來越多,開發的時候明顯感覺到頁面載入速度慢了,network裡看到 bundle.js
體積巨大了,才會想著去做優化的考慮。
emmm 所以到底應該怎麼拆?拆哪些部分?這個需要webpack-bundle-analyzer
來幫忙,code split 也要有理有據。
安裝和配置
如果你跟我一樣,使用的是 [email protected]
的話,webpack-bundle-analyzer
外掛是已經安裝了的,webpack 也配置好了的。
反正你就全域性搜尋一下 webpack-bundle-analyzer
就好了,看看 package.json
中有沒有依賴,webpack
配置中有沒有,一般只在webpack.prod.conf.js
中,因為開發環境下也不會去看的。
如果實在沒有,那就手動安裝和配置好了。
npm intall webpack-bundle-analyzer –save-dev
在build/webpack.prod.config.js中新增配置:
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
在 package.json
的 script
中新增:
“analyz”: “NODE_ENV=production npm_config_report=true npm run build”
如果你是window 使用者的話,應該是:
“analyz”: “set NODE_ENV=production npm_config_report=true npm run build”
執行: npm run analyz
等專案 build 完了之後,就會自動開啟一個頁面了,
4. element-ui 庫的優化
重點終於來了(不是標題黨。。。。)。從上面的圖中我們可以看到,vendor.xxx.js
實在是有點大,webpack build 完了之後,也細心的為我們標註出了 big
:
解決辦法是對於 element-ui
這個 ui 庫從 vendor.xx.js
檔案中剝離出來,最簡單的辦法就是使用 公共的cdn了。這裡再做一層更徹底的剝離,將vue
, vuex
, vue-router
,axios
等依賴檔案,全部使用cdn。
看好這些依賴的版本,直接去 百度搜索相關的 cdn 檔案。下面我直接貼我修改之後的程式碼:
index.html
...
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
...
<body>
<div id="app"></div>
<!-- cdn 加速,減小 vendor.js 體積 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- built files will be auto injected -->
</body>
package.json
上面引入過 cdn 檔案的依賴, 全都可以去掉了。
main.js
刪除或者註釋跟element
相關的程式碼:
import ElementUI from 'element-ui';
...
import 'element-ui/lib/theme-chalk/index.css';
...
Vue.use(ElementUI);
...
webpack.base.conf.js
在 webpack 配置中新增外部擴充套件:
module.exports = {
...
// 外部擴充套件,通過 cdn 引入,不會被webpack打包
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
}
這個時候已經好了,清除一下專案 node_modules
中的刪除的不需要的依賴吧, uninstall
也行,直接刪除整個 node_modules
資料夾,重新 npm install
也行。
處理完 node_modules
之後, npm start
再次看一下我們優化之後的結果:
開發狀態下的 app.js
明顯已經變小了,build 之後的檔案也是。
這裡需要注意的一點是,依賴庫使用 cdn 檔案來載入話,網路請求的速度與 cdn 的速度有關,如果不放心別人的 cdn ,將上述的 cdn 檔案內容下載到本地放在 static
目錄下當做靜態檔案即可。
建議使用 CDN 引入依賴的使用者在連結地址上鎖定版本,以免將來升級時受到非相容性更新的影響。
vue 專案的 code split ,差不多就是這樣了。感謝閱讀, Happy Coding !