最近用element來作項目,在開發的過程當中,忽然發現頁面的操做和切換在數據量大的時候至關卡,後來提了個issue,在furybean解答後才知道,我每一個單元格都加了tooltip,會生成大量的節點,形成頁面操做卡頓。後來將tooltip去掉,操做流暢多了。vue
可是,因爲我是將頁面的數據存在vuex中的,在路由切換回來的時候,發如今數據量大的時候,頁面渲染得很慢,大概兩三秒才能切換過來,用戶體驗至關很差。git
這時,我就在想,能不能讓頁面切換完成以後纔開始渲染數據量大的組件,用戶起碼不會感知到路由切換的卡頓狀況。github
一開始不知道怎樣作,後來看到這篇blog:vue 性能優化,做者基於vue1.0作了一個指令,基本原理是利用v-if來控制組件的渲染時機。做者在回答中提到vue2.0能夠用組件來作,具體的討論能夠看這裏vuex
基於此,我作了個組件vue-lazy-render,歡迎star。segmentfault
延遲加載組件數組
控制延遲加載的時間性能優化
能夠監控數組的變化和設定數據量來決定是否開啓延遲加載微信
<lazy-render> <my-component></my-component> </lazy-render>
<lazy-render :data="myArray" :time="300" :limit="50" track-by-data> <my-component :data="myArray"></my-component> </lazy-render>
<div class="lazy-load"> <slot v-if="show"></slot> <div v-if="!show" :class="[maskClass ? maskClass : 'lazy-load-mask']">{{tip}}</div> </div>
property | description | type | default | required |
---|---|---|---|---|
time | 多長時間後開始渲染組件 | Number | 10 | false |
immediately | 是否當即開啓延遲渲染,vue-lazy-render組件會在路由切換時,會進行一次延遲渲染,若是在同一個路由中需常常對某個組件進行延遲渲染,能夠將immediately由false設爲true,就會立刻開啓一次延遲渲染 | Boolean | -- | false |
data | 若是須要延遲加載的組件是由數組渲染的,能夠將數據的數據prop進vue-lazy-render組件,組件會根據配置監測數組變化,決定開啓延遲加載的時機 | array | -- | false |
trackByData | 是否根據data的變化來開啓延遲加載,若是設爲true,需將data prop進來,而且路由切換時不會再進行延遲渲染 | Boolean | -- | false |
limit | 在數據超過多少後纔開啓延遲渲染,須要data和將trackByData設爲true | Number | 30 | false |
maskClass | 等待渲染時的遮罩層樣式 | String | -- | false |
tip | 等待渲染時的提示文字 | String | 正在渲染,請稍候 | false |
/** * 延遲渲染數據,在數據渲染完成後觸發loaded事件 */ showLazy() { if ((this.data && this.data.length > this.limit) || !this.data) { // 若是數據存在而且數據的數量比限定的數量大,則開啓延遲渲染 若是不是列表調用組件,也開啓延遲渲染 this.syncLoader() } else { // 其餘狀況,不開啓延遲渲染 this.show = true this.$emit('loaded') } }, /** * 延遲渲染 */ syncLoader() { this.show = false setTimeout(() => { this.show = true this.$emit('loaded') },this.time) }
定義的方法很簡單,在data定義的show初始值爲false,在須要延遲加載時,會用一個setTimeout來將show設爲true,當show變爲true時,組件才能夠渲染,從而達到延遲渲染的目的。組件開始渲染時,會觸發loaded事件。性能
created() { this.showLazy() }, watch: { data() { // 數據變化時從新渲染 if (this.trackByData) { this.showLazy() } }, // 路由變化,從新渲染 $route() { if (!this.trackByData) { this.showLazy() } }, // 當即從新變爲true時,從新渲染 immediately() { if (this.immediately) { this.showLazy() } }, },
在頁面進入時,開啓優化
若是不是track-by-data模式,則每次路由切換時,開啓
若是是track-by-data模式,則數組變化時,開啓。因爲個人頁面中,有些表格是在彈層中展現的,同一個組件,可能每次打開彈層時,數據都不同,一開始打算用這種方法來實現延遲的,後來加了immediately,感受這個track-by-data模式徹底沒有意義了,用了反應會形成沒必要要的從新渲染。
當immediately由false變爲true時,開啓
最後,全部文章都會同步發送到微信公衆號上,歡迎關注,歡迎提意見: