寫這篇文章的目的主要在於剛纔看了一位掘友的文章,可是我看了他的代碼有點粗糙,甚至是我以爲沒法做爲一篇好的給予新手的引導文章。javascript
這裏我先抱歉一聲,由於我這樣作有損你的聲譽。php
先放上該掘友的文章,仍是很不錯的,只是但願多點註解會更好:css
https://juejin.im/post/5d9ff02df265da5baf4104d9#commenthtml
優化項目啓動速度,和性能vue
二、必要的清理數據java
第一點是核心,第二點呢其實主要是清理consolenode
一、cdn加載react
二、壓縮jswebpack
三、減小項目在首次加載的時長(首屏加載優化)ios
cdn加載不比多說,就是改成引入外部js路徑
首屏加載優化方面主要其實就兩點
第一:
儘量的減小首次加載的文件體積,和進行分佈加載,這是咱們今天主要講的
第二:
首屏加載最好的解決方案就是ssr(服務端渲染),還利於seo
可是通常狀況下沒太多人選擇ssr,由於只要不須要seo,ssr更多的是增長了項目開銷和技術難度的。不少公司是不會這樣選擇的
這塊我先講,由於篇幅較小,主要也是各大公司已經總結的
一、nuxt.js,地址:https://zh.nuxtjs.org
二、egg.js解決方案:地址:https://www.yuque.com/easy-team
我我的喜歡阿里團隊的方式,畢竟性能更好,可是呢技術要求也更高。
注意語雀的鏈接進去,react和vue都有。因此很全面的。
這個我用的是vueCLi3.X因此壓縮js沒必要說,自帶的。
說明:開啓gzip表明你項目實際環境就可使用gzip。
還有打包的時候不是你打出來的總體包越小越好,雖然從基本面上看確實如此。可是會有幾個狀況影響你打包的文件大小。
好比map.js文件還有gzip文件。
特別是gzip文件你是不能夠刪除原文件的。若是刪除了原文件那麼不支持的瀏覽器就炸了。因此,最好的方式是用瀏覽器的f12來觀測是最好的
緣由:
第一:瀏覽器須要支持
第二:須要後端配置,這裏提供nginx方式:
http:{
gzip on; #開啓或關閉gzip on off
gzip_disable "msie6"; #不使用gzip IE6
gzip_min_length 100k; #gzip壓縮最小文件大小,超出進行壓縮(自行調節)
gzip_buffers 4 16k; #buffer 不用修改
gzip_comp_level 8; #壓縮級別:1-10,數字越大壓縮的越好,時間也越長
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 壓縮文件類型
}
複製代碼
gizp部分:
npm install compression-webpack-plugin
下面是個人vue.config.js
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const productionGzipExtensions = [
"js",
"css",
"svg",
"woff",
"ttf",
"json",
"html"
];
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/" : "/", //部署應用包時的基本 URL
outputDir: "dist", //打包目錄
indexPath: "index.html",
configureWebpack: {
plugins: [
//開啓gzip壓縮
new CompressionWebpackPlugin({
filename: "[path].gz[query]",
test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
threshold: 10240,
minRatio: 0.8, //壓縮率大於0.8的才壓縮
deleteOriginalAssets: false //是否刪除原文件
})
]
},
productionSourceMap: false, //不輸出map文件
devServer: {}
};複製代碼
這裏performance就是關閉每次打包以後的文件過大警告
optimization這個比較複雜,主要是拆分js和抽離公共js的。
提供一篇csdn的文章:https://blog.csdn.net/weixin_43678786/article/details/85788759
webpack官方文檔:https://webpack.docschina.org/configuration/optimization/
configureWebpack: {
//關閉文件過大提示,利於打包加快速度
performance: {
hints: "warning",
//入口起點的最大致積
maxEntrypointSize: 50000000,
//生成文件的最大致積
maxAssetSize: 30000000,
//只給出 js 文件的性能提示
assetFilter: function(assetFilename) {
return assetFilename.endsWith(".js");
}
},
//公共代碼抽離和代碼分割,避免單個js文件過大
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "all",
test: /node_modules/,
name: "vendor",
minChunks: 1,
maxInitialRequests: 5,
minSize: 30000,
priority: 100
},
common: {
chunks: "all",
test: /[\\/]src[\\/]js[\\/]/,
name: "common",
minChunks: 3,
maxInitialRequests: 5,
minSize: 30000,
priority: 60
},
styles: {
name: "styles",
test: /\.(sa|sc|c)ss$/,
chunks: "all",
enforce: true
},
runtimeChunk: {
name: "manifest"
}
}
}
}
},複製代碼
這個項目上線那是基本上必須的,因此也提供下。
有兩種方式
第一種:babel方式
npm install babel-plugin-transform-remove-console --save-dev
babel.config.js文件改成
let plugins = [];
if (process.env.NODE_ENV === "production") {
plugins.push("transform-remove-console");
}
module.exports = {
plugins: plugins,
presets: ["@vue/app"]
};複製代碼
第二種:webpack方式
npm install uglifyjs-webpack-plugin
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/" : "/", //部署應用包時的基本 URL
outputDir: "miniprogram", //打包目錄
indexPath: "index.html",
configureWebpack: {
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true, //console
drop_debugger: true,
pure_funcs: ["console.log"] //移除console
}
}
})
]
}
}
};
複製代碼
關閉eslint關於console的提示。很煩的。
.eslintrc.js文件
rules: {
"no-console": "off",
"no-debugger": "off"
},複製代碼
這裏我是基礎的項目模版,因此沒有加入axios,可是原理一致。
整體來講能用cdn加載的js均可以這樣幹。可是我必須作出說明該方式的有點和缺點。
缺點:
a、項目依賴會比較難以處理,畢竟所有放index.html下面真的很醜
b、對於大廠來講或者說帶寬夠高的狀況下,對於首屏渲染的差異較小。
緣由在於,改用cdn加載主要是下降服務器流量,可是js加載只是放在了別服務器,難道也不須要加載了?因此有用,可是呢必定規模後會有弊端出現。
下面是我把vue的基本三要素都改成cdn加載了
包含,vuerouter,vue,vuex
main.js文件
//import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");複製代碼
router.js
這個路由懶加載必須的,這個也很影響首屏加載。(必須)
//import Vue from "vue";
//import Router from "vue-router";
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: () => import("./views/Home.vue")
},
{
path: "/about",
name: "about",
component: () => import("./views/About.vue")
}
]
});
複製代碼
store.js
//import Vue from "vue";
//import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
ceshi: "dht"
},
mutations: {},
actions: {}
});
複製代碼
最後是打包出來的結果:
很小吧,並且我初步試驗過,對於scss的處理和scpoe(css樣式不衝突)沒有影響,vuex也是正常運行。
而後這是我僅僅是把vue加載註釋去掉
就加了60kb
這是掘友提供的,文章第三次修改。
這個方式的優勢是不須要刪除上述三個文件的代碼,直接就能夠拿來用。
擴展一下,該方法也能夠做爲不打包指定的js的方式。
官方文檔的解釋:若是咱們想引用一個庫,可是又不想讓webpack打包
修改vue.config.js
configureWebpack:{
externals: {
'vue': 'Vue',
"vue-router": "VueRouter",
'vuex': 'Vuex'
}
},複製代碼
把上一步當中關於vue,vuex,等註釋放開
router.js文件
修改成:
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
export default new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: () => import("./views/Home.vue")
},
{
path: "/about",
name: "about",
component: () => import("./views/About.vue")
}
]
});
複製代碼
這樣就能夠了。這個是後續掘友提供的方法。更加順滑的切換,而且更符合模塊化開發。
我的已經試驗過,而且修正。
不會增長包大小,也不須要註釋import。
這是第四次修改文章,代碼已經提交到git上。
首先是本項目的地址:https://github.com/ht-sauce/performance-optimization
咱們如今大部分都用的是vuecli,可是若是一個老項目的話就不能用vuecli了。因此就須要非cli環境下進行開發。下面是我以前找的兩個非cli環境下的項目
注意該兩個項目最好是放在nginx或者tomcat下運行,若是是webstrom的話直接右鍵運行index.html。直接雙擊html文件是沒法運行的。
一、sea.js
https://github.com/ht-sauce/seajs-vue-spa
二、require.js
https://github.com/ht-sauce/vue-requirejs-spa