Vue-cli 项目优化归纳(打包、源码、用户体验)
前言:vue-cli項(xiàng)目開發(fā)打包部署后,存在問題有首次首頁加載過慢,包括加載緩慢問題,需要進(jìn)行vue項(xiàng)目優(yōu)化。下面是對vue性能優(yōu)化方法進(jìn)行歸納,后面會(huì)對方法進(jìn)行親測。
主要包括:代碼包打包優(yōu)化、編碼優(yōu)化、用戶體驗(yàn)優(yōu)化
?
一、代碼包打包優(yōu)化
可以在谷歌瀏覽器的調(diào)試工具(F12)中看到打包后生成的app.js文件過大;
1、屏蔽sourceMap
進(jìn)行打包源碼上線環(huán)節(jié),需要對項(xiàng)目開發(fā)環(huán)節(jié)的開發(fā)提示信息以及錯(cuò)誤信息進(jìn)行屏蔽,一方面可以減少上線代碼包的大小;另一方面提高系統(tǒng)的安全性。在vuejs項(xiàng)目的config目錄下有三個(gè)文件dev.env.js(開發(fā)環(huán)境配置文件)、prod.env.js(上線配置文件)、index.js(通用配置文件)。vue-cli腳手架在上線配置文件會(huì)自動(dòng)設(shè)置允許sourceMap打包,所以在上線前可以屏蔽sourceMap。如下所示,index.js的配置如下,通用配置文件分別對開發(fā)環(huán)境和上線環(huán)境做了打包配置分類,在build對象中的配置信息中,productionSourceMap修改成false:
module.exports = {dev: {...},build: {// Template for index.htmlindex: path.resolve(__dirname, '../dist/ndindex.html'),// PathsassetsRoot: path.resolve(__dirname, '../dist'),assetsSubDirectory: 'static',assetsPublicPath: './',/*** Source Maps*/productionSourceMap: false, //這里關(guān)閉Source Maps// https://webpack.js.org/configuration/devtool/#productiondevtool: '#source-map',// Gzip off by default as many popular static hosts such as// Surge or Netlify already gzip all static assets for you.// Before setting to `true`, make sure to:// npm install --save-dev compression-webpack-pluginproductionGzip: true,productionGzipExtensions: ['js', 'css','svg'],// Run the build command with an extra argument to// View the bundle analyzer report after build finishes:// `npm run build --report`// Set to `true` or `false` to always turn it on or offbundleAnalyzerReport: process.env.npm_config_report} }
2、對項(xiàng)目代碼中的JS/CSS/SVG(*.ico)文件進(jìn)行g(shù)zip壓縮
在vue-cli腳手架的配置信息中,有對代碼進(jìn)行壓縮的配置項(xiàng),例如index.js的通用配置,productionGzip設(shè)置為true,但是首先需要對compress-webpack-plugin支持,所以需要通過 npm install --save-dev compression-webpack-plugin,gzip會(huì)對js、css文件進(jìn)行壓縮處理;對于圖片進(jìn)行壓縮問題,對于png,jpg,jpeg沒有壓縮效果,對于svg,ico文件以及bmp文件壓縮效果達(dá)到50%,在productionGzipExtensions: ['js', 'css','svg']設(shè)置需要進(jìn)行壓縮的什么格式的文件。對項(xiàng)目文件進(jìn)行壓縮之后,需要瀏覽器客戶端支持gzip以及后端支持gzip。下面可以查看成功支持gzip狀態(tài):
module.exports = {dev: {...},build: {...// Gzip off by default as many popular static hosts such as// Surge or Netlify already gzip all static assets for you.// Before setting to `true`, make sure to:// npm install --save-dev compression-webpack-pluginproductionGzip: true,productionGzipExtensions: ['js', 'css','svg'],...} }?
?
二、源碼優(yōu)化
1、對路由組件進(jìn)行懶加載
?懶加載也叫延遲加載,即在需要的時(shí)候進(jìn)行加載,隨用隨載。
在路由配置文件里,這里是router.js里面引用組件。如果使用同步的方式加載組件,在首屏加載時(shí)會(huì)對網(wǎng)絡(luò)資源加載加載比較多,資源比較大,加載速度比較慢。所以設(shè)置路由懶加載,按需加載會(huì)加速首屏渲染。在沒有對路由進(jìn)行懶加載時(shí),在Chrome里devtool查閱可以看到首屏網(wǎng)絡(luò)資源加載情況(6requests 3.8MB transfferred Finish:4.67s DOMContentLoaded 2.61s Load 2.70s)。在對路由進(jìn)行懶加載之后(7requests 800kb transffered Finish2.67s DOMContentLoaded 1.72s Load 800ms),可以看見加載速度明顯加快。但是進(jìn)行懶加載之后,實(shí)現(xiàn)按需加載,那么項(xiàng)目打包不會(huì)把所有js打包進(jìn)app.[hash].js里面,優(yōu)點(diǎn)是可以減少app.[hash].js體積,缺點(diǎn)就是會(huì)把其它js分開打包,造成多個(gè)js文件,會(huì)有多次https請求。如果項(xiàng)目比較大,需要注意懶加載的效果
使用如下:
routes: [{ path: "/", redirect: "index" },{path: "/",name: "home",component: resolve=>require(["@/views/home"],resolve),children: [{// 員工查詢path: "/employees",component: resolve=>require(["@/components/employees"],resolve)},{// 首頁path: "/index",component: resolve=>require(["@/views/index"],rolve)},]} ]?
?
2、組件異步加載
vue官網(wǎng)指南,提到異步組件的使用,在大型應(yīng)用中,我們可能需要將應(yīng)用分割成小一些的代碼塊,并且只在需要的時(shí)候才從服務(wù)器加載一個(gè)模塊。Vue 只有在這個(gè)組件需要被渲染的時(shí)候才會(huì)觸發(fā)工廠函數(shù),且會(huì)把結(jié)果緩存起來供未來重渲染。
2.1、v-if惰性結(jié)合setTimeout 使組件異步加載
加載首頁的時(shí)候,可以先給首頁的子組件設(shè)置v-if = “false”,在頁面初始化的時(shí)候再給子組件設(shè)置為true,此方法利用了v-if的惰性,setTimeout會(huì)使子組件在所有的組件初始化完成并顯示后再對其子組件進(jìn)行初始化。
注:在實(shí)際開發(fā)中還遇到了另一種情況也可以用此方法解決,在入口js中獲取了app的token,但是在具體頁面中發(fā)現(xiàn)不管是在created還是mounted中都是有時(shí)候能獲取到token,有時(shí)候又不可以,是因?yàn)閳?zhí)行順序的原因,可以通過 setTimeout 時(shí)間設(shè)置為0 這種方法把用到token的請求方法給排到最后,這樣就能保證請求方法中有token了。
?
? ? 2.2、異步組件,按需加載
webpack 2 結(jié)合 ES2015 語法如下。
Vue.component('async-webpack-example',// 這個(gè) `import` 函數(shù)會(huì)返回一個(gè) `Promise` 對象。() => import('./my-async-component') )上面全局組件,當(dāng)使用局部注冊的時(shí)候如下,因?yàn)閕mport函數(shù)返回的是一個(gè)promise對象,因此可以用promise本身的then()和catch()方法去監(jiān)聽到組件的加載。
new Vue({// ...components: {'my-component': () => import('./my-async-component')} })?
?
3、vue-lazyload插件,圖片懶加載
項(xiàng)目中過多的圖片會(huì)嚴(yán)重影響網(wǎng)頁的加載速度,并且移動(dòng)網(wǎng)絡(luò)下的流量消耗巨大,所以說延遲加載幾乎是標(biāo)配了。?? 圖片懶加載,顯示當(dāng)前用戶界面再加載顯示圖片,實(shí)現(xiàn)的原理很簡單,就是我們先設(shè)置圖片的data-set屬性(當(dāng)然也可以是其他任意的,只要不會(huì)發(fā)送http請求就行了,作用就是為了存取值)值為其圖片路徑,由于不是src,所以不會(huì)發(fā)送http請求。 然后我們計(jì)算出頁面scrollTop的高度和瀏覽器的高度之和, 如果圖片舉例頁面頂端的坐標(biāo)Y(相對于整個(gè)頁面,而不是瀏覽器窗口)小于前兩者之和,就說明圖片就要顯示出來了(合適的時(shí)機(jī),當(dāng)然也可以是其他情況),這時(shí)候我們再將 data-set 屬性替換為 src 屬性即可。
3.1、JavaScript實(shí)現(xiàn):
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Lazyload 2</title><style>img {display: block;margin-bottom: 50px;height: 200px;}</style> </head> <body><img src="images/loading.gif" data-src="images/1.png"><img src="images/loading.gif" data-src="images/2.png"><img src="images/loading.gif" data-src="images/3.png"><img src="images/loading.gif" data-src="images/4.png"><img src="images/loading.gif" data-src="images/5.png"><img src="images/loading.gif" data-src="images/6.png"><script>function throttle(fn, delay, atleast) {//函數(shù)綁定在 scroll 事件上,當(dāng)頁面滾動(dòng)時(shí),避免函數(shù)被高頻觸發(fā),var timeout = null,//進(jìn)行去抖處理startTime = new Date();return function() {var curTime = new Date();clearTimeout(timeout);if(curTime - startTime >= atleast) {fn();startTime = curTime;}else {timeout = setTimeout(fn, delay);}}}function lazyload() {var images = document.getElementsByTagName('img');var len = images.length;var n = 0; //存儲(chǔ)圖片加載到的位置,避免每次都從第一張圖片開始遍歷 return function() {var seeHeight = document.documentElement.clientHeight;var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;for(var i = n; i < len; i++) {if(images[i].offsetTop < seeHeight + scrollTop) {if(images[i].getAttribute('src') === 'images/loading.gif') {images[i].src = images[i].getAttribute('data-src');}n = n + 1;}}}}var loadImages = lazyload();loadImages(); //初始化首頁的頁面圖片window.addEventListener('scroll', throttle(loadImages, 500, 1000), false);//函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)處理, //500ms 的延遲,和 1000ms 的間隔,當(dāng)超過 1000ms 未觸發(fā)該函數(shù),則立即執(zhí)行該函數(shù),不然則延遲 500ms 執(zhí)行該函數(shù)</script> </body> </html>?
3.2、vue-cli項(xiàng)目中vue-lazyload 插件實(shí)現(xiàn)
3.2.1. 安裝插件:
npm install vue-lazyload --save-dev3.2.2. main.js引入插件:
import VueLazyLoad from 'vue-lazyload' Vue.use(VueLazyLoad,{error:'./static/error.png',loading:'./static/loading.png' })3.2.3. vue文件中將需要懶加載的圖片綁定 v-bind:src 修改為 v-lazy?
<img class="item-pic" v-lazy="newItem.picUrl"/>?功能擴(kuò)展:
圖片懶加載的簡單效果已經(jīng)實(shí)現(xiàn)了,然后就可以按這開發(fā)文檔的api進(jìn)行擴(kuò)展了:
| preLoad | proportion of pre-loading height(預(yù)加載高度比例) | 1.3 | Number |
| error | src of the image upon load fail(圖片路徑錯(cuò)誤時(shí)加載圖片) | 'data-src' | String |
| loading | src of the image while loading(預(yù)加載圖片) | 'data-src' | String |
| attempt | attempts count(嘗試加載圖片數(shù)量) | 3 | Number |
| listenEvents | events that you want vue listen for (想要監(jiān)聽的vue事件) 默認(rèn)['scroll']可以省略, 當(dāng)插件跟頁面中的動(dòng)畫或過渡等事件有沖突是, 可以嘗試其他選項(xiàng) | ['scroll'(默認(rèn)), 'wheel', 'mousewheel', 'resize', 'animationend', 'transitionend', 'touchmove'] | Desired Listen Events |
| adapter | dynamically modify the attribute of element (動(dòng)態(tài)修改元素屬性) | { } | Element Adapter |
| filter | the image's listener filter(動(dòng)態(tài)修改圖片地址路徑) | { } | Image listener filter |
| lazyComponent | lazyload component | false | Lazy Component |
| dispatchEvent | trigger the dom event | false | Boolean |
| throttleWait | throttle wait | 200 | Number |
| observer | use IntersectionObserver | false | Boolean |
| observerOptions | IntersectionObserver options | { rootMargin: '0px', threshold: 0.1 } | IntersectionObserver |
?
?
4、引入外部插件或CDN引用,不要在vue中引入
我們可以打包? 時(shí)不打包 vue、vuex、vue-router、axios 等,換用國內(nèi)的?bootcdn?直接引入到根目錄的 index.html 中,這樣可以減少app.js大小。采用CDN外部加載,去掉其他頁面的組件import,修改webpack.base.config.js,在externals中加入該組件,這是為了避免編譯時(shí)找不到組件報(bào)錯(cuò)。
<script src="//cdn.bootcss.com/vue/2.2.5/vue.min.js"></script> <script src="//cdn.bootcss.com/vue-router/2.3.0/vue-router.min.js"></script> <script src="//cdn.bootcss.com/vuex/2.2.1/vuex.min.js"></script> <script src="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script> externals: {'vue': 'Vue','vue-router': 'VueRouter','vuex': 'Vuex','axios': 'axios' }?
?
5、使用到第三方庫的時(shí)按需引用
在項(xiàng)目開發(fā)中,我們會(huì)用到很多第三方庫,如果可以按需引入,我們可以只引入自己需要的組件,來減少組件庫所占空間,如element-ui組件庫按需只加載部分組件Button、Select,官網(wǎng)?按需引入element-ui
5.1.????安裝babel-plugin-component插件:
npm install babel-plugin-component -D5.2.????配置插件,將?.babelrc修改為:
{"presets": [["es2015", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]] }5.3.????引入部分組件,比如 Button 和 Select,那么需要在 main.js 中寫入以下內(nèi)容:
import Vue from 'vue'; import { Button, Select } from 'element-ui'; import App from './App.vue';Vue.component(Button.name, Button); Vue.component(Select.name, Select); /* 或?qū)憺? Vue.use(Button)* Vue.use(Select)*/new Vue({el: '#app',render: h => h(App) });?
?
三、用戶體驗(yàn)優(yōu)化
1、loading加載效果
用于加載數(shù)據(jù)時(shí)顯示動(dòng)效。當(dāng)請求服務(wù)端接口需要一定時(shí)間時(shí),在請求時(shí)加上一個(gè)loading 加載動(dòng)畫效果將極大提升用戶體驗(yàn)和減輕服務(wù)端壓力。
?
實(shí)現(xiàn)方案:
a、使用elementUI的loading組件,可以通過指令或服務(wù)的形式調(diào)用。
指令形式調(diào)用:可以自定義加載動(dòng)畫的文字、遮罩層顏色、spinner加載圖標(biāo)的類名,如下:
<template><el-tablev-loading="loading"element-loading-text="拼命加載中"element-loading-spinner="el-icon-loading"element-loading-background="rgba(0, 0, 0, 0.8)":data="tableData"style="width: 100%"><el-table-columnprop="date"label="日期"width="180"></el-table-column><el-table-columnprop="name"label="姓名"width="180"></el-table-column><el-table-columnprop="address"label="地址"></el-table-column></el-table> </template><script>export default {data() {return {tableData: [{date: '2016-05-03',name: '王小虎',address: '上海市普陀區(qū)金沙江路 1518 弄'}, {date: '2016-05-02',name: '王小虎',address: '上海市普陀區(qū)金沙江路 1518 弄'}, {date: '2016-05-04',name: '王小虎',address: '上海市普陀區(qū)金沙江路 1518 弄'}],loading: true};}}; </script>上述loading布爾值可以結(jié)合vuex狀態(tài)進(jìn)行全局控制是否展示loading效果;
?
?
?
引入 Loading 服務(wù):
import { Loading } from 'element-ui';在需要調(diào)用時(shí):
Loading.service(options);其中?options?參數(shù)為 Loading 的配置項(xiàng),具體見下表。LoadingService?會(huì)返回一個(gè) Loading 實(shí)例,可通過調(diào)用該實(shí)例的?close?方法來關(guān)閉它:
let loadingInstance = Loading.service(options); this.$nextTick(() => { // 以服務(wù)的方式調(diào)用的 Loading 需要異步關(guān)閉loadingInstance.close(); });需要注意的是,以服務(wù)的方式調(diào)用的全屏 Loading 是單例的:若在前一個(gè)全屏 Loading 關(guān)閉前再次調(diào)用全屏 Loading,并不會(huì)創(chuàng)建一個(gè)新的 Loading 實(shí)例,而是返回現(xiàn)有全屏 Loading 的實(shí)例:
let loadingInstance1 = Loading.service({ fullscreen: true }); let loadingInstance2 = Loading.service({ fullscreen: true }); console.log(loadingInstance1 === loadingInstance2); // true此時(shí)調(diào)用它們中任意一個(gè)的?close?方法都能關(guān)閉這個(gè)全屏 Loading。
如果完整引入了 Element,那么 Vue.prototype 上會(huì)有一個(gè)全局方法?$loading,它的調(diào)用方式為:this.$loading(options),同樣會(huì)返回一個(gè) Loading 實(shí)例
?
?
?
b、可以使用命令【npm install --save vue-element-loading】安裝該插件后直接使用
使用:
import Vue from 'vue'import VueElementLoading from 'vue-element-loading'Vue.component('VueElementLoading', ElementLoading)Or
import VueElementLoading from 'vue-element-loading'export default {components: {VueElementLoading}}?
//全屏 <vue-element-loading :active="isActive" :is-full-screen="true"/>//組件內(nèi)容器 <div class="my-container"><vue-element-loading :active="isActive" spinner="bar-fade-scale" color="#FF6700"/><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.Fusce id fermentum quam. Proin sagittis, nibh id hendrerit imperdiet, elit sapien laoreet elit.</span> </div>Options
| active | Boolean | - | Status for show/hide loading |
| spinner | String | spinner | Spinner icon name: spinner, mini-spinner, ring, line-wave, line-scale, line-down, bar-fade, bar-fade-scale |
| color | String | #ccc | Color of spinner icon |
| is-full-screen | Boolean | false | Loader will overlay the full page |
| background-color | String | rgba(255, 255, 255, .9) | Background color of spinner icon (for overlay) |
| size | String | 40 | The size to display the spinner in pixels (NOTE: this will not affect custom spinner images) |
| duration | String | 0.6 | The duration of one 'loop' of the spinner animation, in seconds (NOTE: this will not affect custom spinner images) |
| text | String | - | Text will appear below loader |
| text-style | Object | {} | Change style of the text below loader |
?
使用參考網(wǎng)址:https://biigpongsatorn.github.io/#/vue-element-loading可以看到有不同的loading動(dòng)畫效果,如下圖
?
?
?
2、骨架屏加載
背景:使用Vue和Webpack進(jìn)行**MPA(單、多頁面應(yīng)用)**的開發(fā),一般會(huì)在頁面進(jìn)行數(shù)據(jù)接口等待時(shí)增加Loading動(dòng)畫,為用戶提供較好的交互體驗(yàn)。但是會(huì)發(fā)現(xiàn),Loading展示的時(shí)機(jī)是在Vue框架解析后,也就是說需要如下幾個(gè)條件才能顯示:
- HTML文件加載完成
- JavaScript文件加載完成
- window對象中完成webpackJsonp方法的添加
因此:等待的時(shí)間=HTML加載時(shí)間+JS加載時(shí)間+JS全局環(huán)境創(chuàng)建的執(zhí)行時(shí)間。若是JS資源文件較大,或者存在過多的圖片資源,導(dǎo)致資源速度下載較慢時(shí),用戶所能看到的白屏?xí)r間便較長。
因此添加骨架屏,其優(yōu)勢在于:
- 寫于HTML文件中,獨(dú)立于Vue框架,節(jié)省了JS加載時(shí)間+JS全局環(huán)境創(chuàng)建的執(zhí)行時(shí)間的時(shí)間
- 只在主頁面根據(jù)頁面結(jié)構(gòu)獨(dú)立編寫,預(yù)先展示頁面結(jié)構(gòu),進(jìn)行視覺暫留,提供更好的交互感官
- 只在頁面結(jié)構(gòu)變化時(shí)進(jìn)行修改,維護(hù)成本相對較低
骨架屏的作用主要是在網(wǎng)絡(luò)請求較慢時(shí),提供基礎(chǔ)占位,當(dāng)數(shù)據(jù)加載完成,恢復(fù)數(shù)據(jù)展示。這樣給用戶一種很自然的過渡,不會(huì)造成頁面長時(shí)間白屏或者閃爍等情況。 常見的骨架屏實(shí)現(xiàn)方案有ssr服務(wù)端渲染和prerender兩種解決方案。
?
詳細(xì)使用見本人文章:(親測)vue-cli項(xiàng)目添加骨架屏多種方式,自動(dòng)生成骨架屏
?
?
?
?
PS:
一些開發(fā)經(jīng)驗(yàn)或習(xí)慣可以參考文章:https://blog.csdn.net/crazywoniu/article/details/73480344
可以學(xué)習(xí)的有:
- v-show,v-if 選擇哪個(gè)??v-if,因?yàn)闇p少了 dom 數(shù)量,加快首屏渲染,v-if是懶加載,當(dāng)狀態(tài)為true時(shí)才會(huì)加載,并且為false時(shí)不會(huì)占用布局空間;v-show是無論狀態(tài)是true或者是false,都會(huì)進(jìn)行渲染,并對布局占據(jù)空間對于在項(xiàng)目中,需要頻繁調(diào)用,不需要權(quán)限的顯示隱藏,可以選擇使用v-show,可以減少系統(tǒng)的切換開銷。。
- 盡量不在模板里面寫過多的表達(dá)式與判斷?v-if="isShow && isAdmin && (a || b)",這種表達(dá)式雖說可以識(shí)別,但是不是長久之計(jì),當(dāng)看著不舒服時(shí),適當(dāng)?shù)膶懙?methods 和 computed 里面封裝成一個(gè)方法,這樣的好處是方便我們在多處判斷相同的表達(dá)式,其他權(quán)限相同的元素再判斷展示的時(shí)候調(diào)用同一個(gè)方法即可。
- 循環(huán)調(diào)用子組件時(shí)添加 key,如?(item, index) in arr,然后?:key="index"來確保 key 的唯一性。在列表數(shù)據(jù)進(jìn)行遍歷渲染時(shí),需要為每一項(xiàng)item設(shè)置唯一key值,方便vuejs內(nèi)部機(jī)制精準(zhǔn)找到該條列表數(shù)據(jù)。當(dāng)state更新時(shí),新的狀態(tài)值和舊的狀態(tài)值對比,較快地定位到diff。
- 組件內(nèi)樣式命名盡量采用簡短的命名規(guī)則,不需要?.header-title__text?之類的 class,直接?.title?搞定。
- 全局的樣式文件,盡量抽象化,既然不在每一個(gè)組件里重復(fù)寫,就盡量通用,這部分抽象做的越好說明你的樣式文件體積越小,復(fù)用率越高。建議將復(fù)寫組件庫如 Element 樣式的代碼也放到全局中去。
- 盡量不使用 float 布局,之前看到很多人封裝了?.fl -- float: left?到全局文件里去,然后又要?.clear,現(xiàn)在的瀏覽器還不至于弱到非要用?float?去兼容,完全可以 flex,grid 兼容性一般,功能其實(shí) flex 布局都可以實(shí)現(xiàn),float 會(huì)帶來布局上的麻煩,用過的都知道不相信解釋坑了。
- 盡量保持每個(gè)組件?export default {}?內(nèi)的方法順序一致,方便查找對應(yīng)的方法。我個(gè)人習(xí)慣 data、props、鉤子、watch、computed、components。
- props 父子組件傳值時(shí)盡量?:width="" :heigth=""?不要?:option={},細(xì)化的好處是只傳需要修改的參數(shù),在子組件 props 里加數(shù)據(jù)類型,是否必傳,以及默認(rèn)值,便于排查錯(cuò)誤,讓傳值更嚴(yán)謹(jǐn)
- watch 和 computed 用哪個(gè)?,計(jì)算屬性主要是做一層 filter 轉(zhuǎn)換,切忌加一些調(diào)用方法進(jìn)去,watch 的作用就是監(jiān)聽數(shù)據(jù)變化去改變數(shù)據(jù)或觸發(fā)事件如?this.$store.dispatch('update', { ... })
- computed 中不能依賴一個(gè)計(jì)算結(jié)果去計(jì)算另一個(gè)計(jì)算值,因?yàn)閏omputed中計(jì)算值是異步的,可能會(huì)報(bào)錯(cuò)undefined;。當(dāng)watch的數(shù)據(jù)比較小,性能消耗不明顯。當(dāng)數(shù)據(jù)變大,系統(tǒng)會(huì)出現(xiàn)卡頓,所以減少watch的數(shù)據(jù)。
- 組件分類,我習(xí)慣性的按照三類劃分,page、page-item 和 layout,page 是路由控制的部分,page-item 屬于 page 里各個(gè)布局塊如 banner、side 等等,layout 里放置多個(gè)頁面至少出現(xiàn)兩次的組件,如 icon, scrollTop 等,組件盡量實(shí)現(xiàn) "高內(nèi)聚低耦合";
- vuex狀態(tài)過大時(shí)可以使用官網(wǎng)提供的模塊化方案,vuex使用建議:盡量跑完完整的閉環(huán)是 store.dispatch('action') -> action -> commit -> mutation -> getter -> computed,為方便后期管理,在我的組件里只出現(xiàn) dispatch 和 mapGetters,其余的流程都在名為 store 的 vuex 文件夾里進(jìn)行。
- SSR(服務(wù)端渲染):如果項(xiàng)目比較大,首屏無論怎么做優(yōu)化,都出現(xiàn)閃屏或者一陣黑屏的情況??梢钥紤]使用SSR(服務(wù)端渲染),vuejs官方文檔提供next.js很好的服務(wù)端解決方案,但是局限性就是目前僅支持Koa、express等Nodejs的后臺(tái)框架,需要webpack支持。目前自己了解的就是后端支持方面,vuejs的后端渲染支持php,其它的不太清楚。
?
?
?
?
參考文章:
淺談 Vue 項(xiàng)目優(yōu)化:https://blog.csdn.net/crazywoniu/article/details/73480344
vuejs項(xiàng)目性能優(yōu)化總結(jié):https://www.jianshu.com/p/41075f1f5297
關(guān)于vue在app首次加載緩慢的解決辦法:https://www.jianshu.com/p/6262772bdc9c
圖片懶加載和預(yù)加載:https://www.cnblogs.com/rlann/p/7296660.html
vue-lazyload 使用:https://www.cnblogs.com/xyyt/p/7650539.html
vue骨架屏官網(wǎng):https://github.com/lavas-project/vue-skeleton-webpack-plugin
vue-element-loading:?https://biigpongsatorn.github.io/#/vue-element-loading
?
總結(jié)
以上是生活随笔為你收集整理的Vue-cli 项目优化归纳(打包、源码、用户体验)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器学习】模型又线上线下不一致怎么办?
- 下一篇: 【深度学习】19家机构联合发布,200页