本文章上接搭建篇,由於篇幅緣由,我把優化單獨放一篇文章來說。css
代碼我都上傳到了github,有須要的自取。Webpack-Vue-Mobilevue
大佬繞路輕噴node
不少時候作開發都會使用UI組件庫,這些組件庫通常都會有按需加載的功能,這裏我選擇vant組件庫來測試。手頭暫時沒有能夠演示的項目,可能有點純理論感受,可是應該能你們一個優化的思路。我會在測試項目裏面寫一些測試頁面,到時上傳到github供你們參考!webpack
注意: 通過我前面的一些實踐,這兒有事情須要告知ios
安裝vantgit
npm install vant
複製代碼
安裝完畢後,咱們先使用官網的全局導入全部組件github
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
複製代碼
而後你到頁面使用幾個組件,好比Button,Dialog這些,運行npm run dev命令,這時發現報錯了,說Module parse failed: Unexpected character '@',這是由於咱們引入vant時,引入了css文件,可是咱們的webpack並無配置處理css的loader,因此加上便可:web
{
test: /\.css$/,
// 這兒組件庫的css通常都是處理過的,咱們使用通常的loader便可
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
}
]
}
複製代碼
這樣咱們就能運行並加入相關組件了,這裏咱們不演示組件使用,而是直接打包展現結果分析圖:正則表達式
咱們能夠看見那個碩大的index.css,也就是說你沒用到的組件它也把樣式這些都弄進來了。
npm install babel-plugin-import -D
複製代碼
安裝完畢後在babel.config.js裏面配置:
// 按需加載vant組件
plugins: [
["import", {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
複製代碼
這樣你在main.js裏面這樣引入便可:
// 按需註冊vant組件
import { Button } from 'vant';
Vue.use(Button);
複製代碼
你使用了什麼組件就註冊什麼組件,目前社區上的許多ui組件庫都是支持按需加載的,有的話必定要使用這種方式。
這下看下,比剛纔所有引入好多了,額。。main.js碩大應該是未分離全部東西打包到一塊兒的緣由-_-!。
使用路由懶加載,在頁面訪問到是再加載對應的資源,提高首頁訪問的速度。 在這以前,咱們還須要一個babel插件來實現這個功能
npm install @babel/plugin-syntax-dynamic-import -D
複製代碼
安裝完畢後,在webpack裏面babel-loader配置加上如下代碼:
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
// 使用vue官方的懶加載語法並結合babel需使用這個插件,否則會報錯
plugins: ["@babel/plugin-syntax-dynamic-import"]
}
}
]
}
複製代碼
而後咱們現有的路由裏面引入組件的寫法須要改變下,好比你如今是這麼寫的:
import Home from '../views/Home.vue';
import RouterTest from '../views/RouterTest.vue';
import VantTest from '../views/VantTest.vue';
複製代碼
改爲下面的寫法:
//官方的懶加載方案,須要在webpack.config.js中配置@babel/plugin-syntax-dynamic-import這個插件,不然babel不支持如下語法會報錯。
//下面的註釋語法是打包生成的js的文件名,若是你想某幾個組件打包到同一個文件,那麼它們的註釋語法的webpackChunkName的名字相同便可
const MainPage = () =>
import(/* webpackChunkName: "group-foo" */ "./views/MainPage.vue");
const ComOne = () =>
import(/* webpackChunkName: "group-foo" */ "./views/ComOne.vue");
const ComTwo = () =>
import(/* webpackChunkName: "group-foo" */ "./views/ComTwo.vue");
複製代碼
這樣處理後你會發現你在切換路由時會加載額外的js文件,這樣咱們就分離了出來按需加載,打包分析圖以下:
這裏能夠發現一個問題,咱們不少包都重複打了,接下來就是去除重複打包。因此咱們要提取公共代碼。
在webpack3的時候,咱們能夠藉助CommonsChunkPlugin來實現,webpack4已經移除了這個插件,在webpack4中能夠用splitChunks。
若是你在使用webpack4的時候沒有作optimization.splitChunks的配置,那麼它會有一個默認配置,官方文檔的代碼塊:
module.exports = {
...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
...
}
複製代碼
大多數狀況咱們須要本身配置cashGroups這個參數,也就是自定義拆分組,這裏我參考了社區大佬的配置,而後優化了下:
optimization: {
splitChunks: {
cacheGroups: {
// node_modules下的模塊拆分到chunk-vendors.xxxx.js下
vendors: {
name: 'chunk-vendors',
test: /[\\\/]node_modules[\\\/]/,
priority: -10,
chunks: 'all'
},
// 本身定義的公告組件超過兩次引用的放在chunk-common.xxxx.js下
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'all',
reuseExistingChunk: true
}
}
}
}
複製代碼
一開始,chunks的屬性值都是initial,而後咱們看一下打包分析圖:
能夠看到分離的js文件都打包了一次core.js文件,因此我把chunks參數值改成all,再來看分析圖:
這樣,就沒有重複打包了。
在翻閱了社區上的一些文章後(官方文檔對於我這個菜雞來講看不出來什麼-_-),在此仍是作一個總結。
chunks 有all、async和initial三個值,async表示只從異步加載得模塊(動態加載import())裏面進行拆分 initial表示只從入口模塊進行拆分 all表示以上二者都包括。
automaticNameDelimiter 打包拆分出來文件名的鏈接符,通常都是~。
maxAsyncRequests 按需加載時的最大並行請求數。
maxInitialRequests 入口並行加載的最大請求數。
minChunks 當應用次數超過多少次時會打包到單獨的塊,通常都是2。
minSize 生成塊的最小大小(以字節爲單位)。
maxSize 這個有點複雜,暫時說不清。#手動捂臉
name 分割的塊名。
cashGroups 緩存組,這個能夠本身來指定你的拆分規則,同時它的參數跟上面同樣,聲明瞭的話就是覆蓋,不然就是繼承,同時它還有幾個獨有的選項
關於這個參數的做用,我引用思否大佬的一個回答:
優化持久化緩存的, runtime 指的是 webpack 的運行環境(具體做用就是模塊解析, 加載) 和 模塊信息清單, 模塊信息清單在每次有模塊變動(hash 變動)時都會變動, 因此咱們想把這部分代碼單獨打包出來, 配合後端緩存策略, 這樣就不會由於某個模塊的變動致使包含模塊信息的模塊(一般會被包含在最後一個 bundle 中)緩存失效。optimization.runtimeChunk 就是告訴 webpack 是否要把這部分單獨打包出來。連接
就是說呢那些不會常常變的runtime把它單獨提出來,不須要頻繁的產生變化,用來優化後端的緩存策略。
那麼在webpack的配置文件加上這句:
optimization: {
runtimeChunk: true,
splitChunks: {
......
}
}
複製代碼
設置好後,咱們打包出來試一試看相比於上面的配置會有哪些區別:
這下你發現main.js進一步減少了,把裏面的部份內容放到了runtime~main下面。
若是還想進一步減少包的體積,除了你的圖片媒體資源這些使用oss外。你的第三方庫也可使用cdn分發網絡,好比個人公司項目的axios,vue,better-scroll這些都使用了cdn分發的方式,而不是直接導入到包裏面一塊兒打包。 在你的index.html入口頁面下以這種方式加入
<script src="https://static.XXXXXX.com/12static/new/js/vue.min.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/vue-router.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/axios.min.js"></script>
<script src="https://static.XXXXXX.com/12static/new/js/bscroll.min.js"></script>
複製代碼
這裏給你們推薦一個開源的第三方cdn分發網絡:BootCDN
暫時到這裏總結就結束了,可是優化的腳步不會停,我這兒的優化都是比較基本的優化,確定還有許多點沒有總結到,後期如有使用到的好的優化方法,會持續更新,若文章有錯誤,還請多多指正!