通常來講,你不須要太關心vue的運行時性能,它在運行時很是快,但付出的代價是初始化時相對較慢。先看一下常見的vue寫法:在html裏放一個app組件,app組件裏又引用了其餘的子組件,造成一棵以app爲根節點的組件樹。html
<div id="app">
<router-view></router-view>
</div>
複製代碼
而正是這種作法引起了性能問題,要初始化一個父組件,必然須要先初始化它的子組件,而子組件又有它本身的子組件。那麼要初始化根標籤,就須要從底層開始冒泡,將頁面全部組件都初始化完。因此咱們的頁面會在全部組件都初始化完纔開始顯示。vue
這個結果顯然不是咱們要的,更好的結果是頁面能夠從上到下按順序流式渲染,這樣可能整體時間增加了,但首屏時間縮減,在用戶看來,頁面打開速度就更快了。webpack
new Vue({
components: {
A: { /*component-config*/ },
B (resolve) {
setTimeout(() => {
resolve({ /*component-config*/ })
}, 0);
}
}
})
複製代碼
或者是ios
const Foo = resolve => {
// require.ensure 是 Webpack 的特殊語法,用來設置 code-split point
// (代碼分塊)
require.ensure(['./Foo.vue'], () => {
resolve(require('./Foo.vue'))
})
}
const Foo = resolve => require(['./Foo.vue'], resolve)
const router = new VueRouter({
routes: [
{ path: '/foo', component: Foo }
]
})
複製代碼
把不一樣路由對應的組件分割成不一樣的代碼塊,而後當路由被訪問的時候才加載對應組件,從而實現路由懶加載web
有時候咱們想把某個路由下的全部組件都打包在同個異步 chunk 中。只須要 給 chunk 命名,提供 require.ensure 第三個參數做爲 chunk 的名稱:vue-router
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')
複製代碼
<head>
<!--some component -->
<div v-if="showB">
<!--some component -->
</div>
<div v-if="showC">
<!--some component -->
</div>
</head>
data: {
showB: false,
showC: false
},
created () {
// 顯示B
setTimeout(() => {
this.showB = true;
}, 0);
// 顯示C
setTimeout(() => {
this.showC = true;
}, 0);
}
複製代碼
這個示例寫起來略顯囉嗦,但它已經實現了咱們想要的順序渲染的效果。頁面會在組件初始化完後顯示,而後再按順序渲染其他的組件,整個頁面渲染方式看起來是流式的。vuex
有些人可能會擔憂v-if存在一個編譯/卸載過程,會有性能影響。但這裏並不須要擔憂,由於v-if是惰性的,只有當第一次值爲true時纔會開始初始化。axios
若是你作用一個大型web的spa的時候,你有不少router,對應的是不少個頁面。在頁面的快速切換中(如常見的tab頁),爲了保證頁面加載的效率,除了緩存機制以外,vue的keep-alive組件能夠幫的上忙。它會把組件保存在瀏覽器內存當中,方便你快速切換。windows
權限問題,只要涉及到權限相關的展現無疑要用 v-if,沒有權限限制下根據用戶點擊的頻次選擇,頻繁切換的使用 v-show,不頻繁切換的使用 v-if,這裏要說的優化點在於減小頁面中 dom 總數,我比較傾向於使用 v-if,由於減小了 dom 數量,加快首屏渲染。 不要在模板裏面寫過多的表達式與判斷 v-if="isShow && isAdmin && (a || b)",這種表達式雖然說能夠識別,可是不是長久之計,當看着不舒服時,適當的寫到 methods 和 computed 裏面封裝成一個方法,這樣的好處是方便咱們在多處判斷相同的表達式,其餘權限相同的元素再判斷展現的時候調用同一個方法便可。promise
循環儘量在使用 v-for 時提供 key,除非遍歷輸出的 DOM 內容很是簡單,或者是刻意依賴默認行爲以獲取性能上的提高。引用vue文檔:當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用「就地複用」策略。若是數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。這個相似 Vue 1.x 的 track-by="$index" 。
這個默認的模式是高效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。
爲了給 Vue 一個提示,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素,你須要爲每項提供一個惟一 key 屬性。理想的 key 值是每項都有的惟一 id。 watch 和 computed 用哪一個的問題看官網的例子,計算屬性主要是作一層 filter 轉換,切忌加一些調用方法進去,watch 的做用就是監聽數據變化去改變數據或觸發事件如 this.$store.dispatch('update', { ... }) 數據請求在哪一個時候儘可能根據需求考慮後,多多利用promise的併發請求。
如打包優化:在打包時可將一些靜態模塊排除,如ue、vuex、vue-router、axios 等,換用國內的 bootcdn 直接引入到根目錄的 index.html 中。在 webpack 裏有個 externals,能夠忽略不須要打包的庫
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
複製代碼
或者是利用webpack的動態連接庫DllPlugin,打包會輸出一個類dll包(dll包源於windows的動態連接庫),這些代碼自己不會執行,主要是提供給咱們的業務代碼引用。將靜態資源文件(運行依賴包)與源文件分開打包,先使用DllPlugin給靜態資源打包,再使用DllReferencePlugin讓源文件引用資源文件。dll在打包一次後便可,下次業務代碼修改也不會從新打包,而後在html裏分模塊引入
<script src="./static/js/vendor.dll.js"></script>
<script src="/dist/build.js"></script>
複製代碼
關於webpack的使用建議閱讀《深刻淺出webpack》一書。 其餘的還有樣式優化、減小組件耦合性等。