前言
最近做了一個小型的vue的h5專案,發現在手機上運行的時候,第一次進去的首頁比較慢,然后同事提了下可以在生產環境用cdn,于是我嘗試了下
生產環境開啟cdn
1、 在vue.congfig.js里面加入
const isProduction = process.env.NODE_ENV == "production";
configureWebpack: (config) => {
if (isProduction) {
config.externals = {
vue: "Vue",
"vue-router": "VueRouter",
vant: "vant",
_: "lodash",
};
另外注意:光理論是不夠的,在此贈送2020最新企業級 Vue3.0/Js/ES6/TS/React/node等實戰視頻教程,想學的可進裙 519293536 免費獲取,小白勿進哦!
externals是讓里面的庫不被webapck打包,也不影響通過import(或者其他AMD、CMD等)方式引入
2、 在index.html引入cdn資源
<link rel="stylesheet" href=https://www.cnblogs.com/chengxuyuanaa/p/"https://cdn.jsdelivr.net/npm/[email protected]/lib/index.css" />
<script src=https://www.cnblogs.com/chengxuyuanaa/p/"https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src=https://www.cnblogs.com/chengxuyuanaa/p/"https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script src=https://www.cnblogs.com/chengxuyuanaa/p/"https://cdn.jsdelivr.net/npm/[email protected]/lib/vant.min.js"></script>
<script src=https://www.cnblogs.com/chengxuyuanaa/p/"https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>
復制代碼
3、 優化下寫法
// vue.config.js
const cdn = {
css: ["https://cdn.jsdelivr.net/npm/[email protected]/lib/index.css"],
js: [
"https://cdn.jsdelivr.net/npm/[email protected]",
"https://unpkg.com/vue-router/dist/vue-router.js",
"https://cdn.jsdelivr.net/npm/[email protected]/lib/vant.min.js",
"https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js",
],
};
chainWebpack: (config) => {
if (isProduction) {
config.plugin("html").tap((args) => {
args[0].cdn = cdn;
return args;
});
}
}
// index.html
<% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css){%>
<link src=https://www.cnblogs.com/chengxuyuanaa/p/"<%= htmlWebpackPlugin.options.cdn.css[i] %>"></link>
<%}%>
<% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js){%>
<script src=https://www.cnblogs.com/chengxuyuanaa/p/"<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<%}%>
復制代碼
優化前
開啟gzip壓縮
cnpm install compression-webpack-plugin --save-dev
// vue.config.js
const CompressionPlugin = require("compression-webpack-plugin");
configureWebpack: (config) => {
if (isProduction) {
config.externals = {
vue: "Vue",
"vue-router": "VueRouter",
vant: "vant",
_: "lodash",
};
config.plugins.push(
new CompressionPlugin({
algorithm: "gzip",
})
);
}
},
復制代碼
路由懶加載
{
path: "/index",
name: "index",
component: () => import("../views/index.vue"),
meta: {
keepAlive: false,
},
},
復制代碼
平常當中經常這么寫,只不過你可能不知道這就是路由懶加載,官網,官網上提到這是由于異步組件和weback的代碼分割code-splitting功能,每個異步路由會打包成不同的塊,實作按需加載,除了上面的ES2015模塊的寫法,它還有
{
path: "/index",
name: "index",
component: (resolve) => require(["../views/index.vue"], resolve),
meta: {
keepAlive: false,
},
},
復制代碼
根據官網提到的,首先創建一個回傳Promise的工廠函式
const Index = () => Promise.resolve({ /* 組件定義物件 */ })
復制代碼
然后用動態 import語法定義代碼分塊的分割點
import ('./Index')
復制代碼
兩者結合,就可以自動分割代碼
const Index = () => import('../views/index.vue')
復制代碼
先看了下這個code-split,
然后去看了下vue-cli的具體配置,路由已經是Dynamic Import,如上圖第二點提到. 下面說說針對于chunk-vendors的分割,正如上圖第三點提到,配置splitChunks是了重復資料洗掉和分割chunks
optimization(開發和生產都是一樣的)
optimization:{
splitChunks: {
cacheGroups: { // 快取組,可以定義多個
vendors: { //創建一個 自定義的vendor的chunk
name: "chunk-vendors",
test: /[\\\/]node_modules[\\\/]/, // 匹配node_modules
priority: -10, // 理解為快取的級別
chunks: "initial",
},
common: {
name: "chunk-common",
minChunks: 2, // 分割之前必須共享模塊的最小chunk數
priority: -20,
chunks: "initial",
reuseExistingChunk: true, // 是否復用存在的塊
},
},
}
}
復制代碼
- cacheGroups 快取組,可以定義多個
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
復制代碼
- priority 快取組的級別
A module can belong to multiple cache groups. The optimization will prefer the cache group with a higher priority. The default groups have a negative priority to allow custom groups to take higher priority (default value is 0 for custom groups)
翻譯過來大概就是一個模塊可以有多個cash groups,optimization將會選擇優先級更高的cash group, default group 的優先級為負數,可以允許custom group有更高的優先級(默認值是0), 簡而言之,custom group可以通過priority比default group高
- reuseExistingChunk 是否復用存在的塊
output配置有些不同
// 生產
output: {
path:"/dist",
filename: "static/js/[name].[contenthash:8].js",
publicPath: "/",
chunkFilename: "static/js/[name].[contenthash:8].js", // 生成一個8位的hash值
}
// 開發
output: {
path:"/dist",
filename: "static/js/[name].js",
publicPath: "/",
chunkFilename: "static/js/[name].js",
}
復制代碼
運行打包
生產輸出了css,而開發環境沒有,估計是生產配置了這句
// 生產
new MiniCssExtractPlugin({
filename: "static/css/[name].[contenthash:8].css",
chunkFilename: "static/css/[name].[contenthash:8].css",
})
復制代碼
那么問題來了
- 開發模式打包出來檔案的css到底怎么引入的
- 打包出來的dist的index.html的link和script標簽引入的檔案為何不同
- preload 和 prefetch的區別
// development
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href=https://www.cnblogs.com/chengxuyuanaa/p/"/favicon.ico">
<title>南藍</title>
<link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/0.js" rel="prefetch"><link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/1.js" rel="prefetch"><link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/2.js" rel="prefetch">
<link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/3.js" rel="prefetch">
<link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/app.js" rel="preload" as="script">
<link href=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/chunk-vendors.js" rel="preload" as="script">
</head>
<body>
<noscript>
<strong>We're sorry but f2e-client doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="text/javascript" src=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/chunk-vendors.js"></script><script type="text/javascript" src=https://www.cnblogs.com/chengxuyuanaa/p/"/static/js/app.js"></script></body>
</html>
復制代碼
再來看看生產打包出來的index.html(production)
// production
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel=icon href=https://www.cnblogs.com/favicon.ico>
鴨嘴獸
<script src=https://cdn.jsdelivr.net/npm/[email protected]/lib/index.css></script>
<script src=https://cdn.jsdelivr.net/npm/[email protected]></script>
<script src=https://unpkg.com/vue-router/dist/vue-router.js></script>
<script src=https://cdn.jsdelivr.net/npm/[email protected]/lib/vant.min.js></script>
<script src=https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js></script>
<link href=/static/css/chunk-0c3564fc.b3594289.css rel=prefetch>
<link href=/static/css/chunk-56255d30.c1e34d24.css rel=prefetch>
<link href=/static/css/chunk-5ba5813d.a56f098f.css rel=prefetch>
<link href=/static/css/chunk-9945b478.66fcd057.css rel=prefetch>
<link href=/static/js/chunk-0c3564fc.9d02dfcc.js rel=prefetch>
<link href=/static/js/chunk-56255d30.d0115acd.js rel=prefetch>
<link href=/static/js/chunk-5ba5813d.10f75234.js rel=prefetch>
<link href=/static/js/chunk-9945b478.dc8a4502.js rel=prefetch>
<link href=/static/css/app.faa29057.css rel=preload as=style>
<link href=/static/css/chunk-vendors.97c56160.css rel=preload as=style>
<link href=/static/js/app.5deb2d45.js rel=preload as=script>
<link href=/static/js/chunk-vendors.158e0179.js rel=preload as=script>
<link href=/static/css/chunk-vendors.97c56160.css rel=stylesheet>
<link href=/static/css/app.faa29057.css rel=stylesheet>
<body>
