引言:
寫這篇文章的目的主要在於剛纔看了一位掘友的文章,但是我看了他的代碼有點粗糙,甚至是我覺得無法作爲一篇好的給予新手的引導文章。
這裏我先抱歉一聲,因爲我這樣做有損你的聲譽。
先放上該掘友的文章,還是很不錯的,只是希望多點註解會更好:
https://juejin.im/post/5d9ff02df265da5baf4104d9#comment
一、知識點和目的
1、打包優化的目的
優化項目啓動速度,和性能
2、必要的清理數據
第一點是核心,第二點呢其實主要是清理console
3、性能優化的主要方向
1、cdn加載
2、壓縮js
3、減少項目在首次加載的時長(首屏加載優化)
4、目前的解決方向
cdn加載不比多說,就是改爲引入外部js路徑
首屏加載優化方面主要其實就兩點
第一:
儘可能的減少首次加載的文件體積,和進行分佈加載,這是我們今天主要講的
第二:
首屏加載最好的解決方案就是ssr(服務端渲染),還利於seo
但是一般情況下沒太多人選擇ssr,因爲只要不需要seo,ssr更多的是增加了項目開銷和技術難度的。很多公司是不會這樣選擇的
二、服務端渲染解決方案提供
這塊我先講,因爲篇幅較小,主要也是各大公司已經總結的
1、nuxt.js,地址:https://zh.nuxtjs.org
2、egg.js解決方案:地址:https://www.yuque.com/easy-team
我個人喜歡阿里團隊的方式,畢竟性能更好,但是呢技術要求也更高。
三、打包優化
1、我們首先是壓縮js,並且開啓gzip
這個我用的是vueCLi3.X所以壓縮js不必說,自帶的。
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: {} };
2、去除不必要的提示和拆分與抽離公共js
這裏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" } } } } },
3、項目去除console.log
這個項目上線那是基本上必須的,所以也提供下。
有兩種方式
第一種: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 } } }) ] } } };
4、項目中能用cdn加載的都用cdn加載
這裏我是基礎的項目模版,所以沒有加入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
四、git地址提供和不使用vueCli下怎麼去實現vue單頁面項目
首先是本項目的地址:https://github.com/ht-sauce/performance-optimization
我們現在大部分都用的是vuecli,但是如果一個老項目的話就不能用vuecli了。所以就需要非cli環境下進行開發。下面是我之前找的兩個非cli環境下的項目
注意該兩個項目最好是放在nginx或者tomcat下運行,如果是webstrom的話直接右鍵運行index.html。直接雙擊html文件是無法運行的。
1、sea.js
https://github.com/ht-sauce/seajs-vue-spa
2、require.js
https://github.com/ht-sauce/vue-requirejs-spa