Vue 性能优化track-by

Vue 是一个MVVM框架

所谓mvvm就是model-->view,view-->model。 vue帮助我们实现了自动绑定。省点我们用JQUERY,zpeto 去操作dom的麻烦。

主要是Object.defineProperty 给object添加get set 访问器来实现值变化的监听。

但是由于es5的限制,有很多不能达到监听值的目点。比如:

1.数组的各个方法,来改变数组

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

2.纯数组 [1,2,3,4,5,6] 这样的也不能监听到值的变化

3.对象:动态添加对象的属性等

这些都不能监听到,不过vue都处理过了,什么$set ,$delete,$remove等等。 es6 浏览器出现了 Object.observe ,Array.observe. 不过兼容性问题也很头疼,可能在以后的各个MVVM框架都会改版吧.

利用Object.freeze() 方法可以阻止vue 给添加get set访问器。 这样能提高性能,但同时也放弃了监听的功能

列表渲染

用v-for 进行列表渲染。这是一个最基本最重要的功能。vue 在设计时为了性能(不能每次一个list更改就要全量的创建dom),提供了track-by特性,用来复用dom和原来的作用域。

<div v-for="item in list">
     {{item}}
   </div>

默认情况下,只要

this.list=[1,2,3,4,5]

就会全部重新渲染。

不用:track-by

不复用也是复用的一种方式

1.在不用track-by 的情况,在遍历数组的时候会给每一个对象 添加一个v-for id,这个东西是要用来在再次渲染的时候用的。所以如果数组中哪个对象,用了Object.freeze。那么它就生成不了这个对象。在第一次之后的任何一次渲染都会失败。这种情况下需要添加track-by,来通知vue 应该怎样去复用

2.在数组数据重复时,在渲染时无法决定如何复用。这时需要添加track-by="$index",来处理。

用:track-by

但是,如果每个对象都有一个唯一 ID 的属性,便可以使用 track-by 特性给 Vue.js 一个提示,Vue.js 因而能尽可能地复用已有实例。

例如,假定数据为:

{
  items: [
    { _uid: '88f869d', ... },
    { _uid: '7496c10', ... }
  ]
}

然后可以这样给出提示:

<div v-for="item in items" track-by="_uid">
  <!-- content -->
</div>

然后在替换数组 items 时,如果 Vue.js 遇到一个包含 _uid: '88f869d' 的新对象,它知道它可以复用这个已有对象的作用域与 DOM 元素。

在这个渲染过程中,在新的items的_uid在 索引 10 处。老的items此_uid 在20处,就会发生dom片段移动。 

如果值发生变化就更新值,(只涉及到绑定的属性,没有绑定的属性,即使改变了也不会渲染,因为没必要。。)

track-by="$index"

如果没有唯一的键供追踪,可以使用 track-by="$index",它强制让 v-for 进入原位更新模式:片断不会被移动,而是简单地以对应索引的新值刷新。这种模式也能处理数据数组中重复的值。

这让数据替换非常高效,但是也会付出一定的代价。因为这时 DOM 节点不再映射数组元素顺序的改变,不能同步临时状态(比如 <input> 元素的值)以及组件的私有状态。因此,如果 v-for 块包含 <input> 元素或子组件,要小心使用 track-by="$index"

按照新的数组来遍历,第几个就是拿老的对应index的dom过来渲染,如果值变化就更新值.没变化就算了。 多余的dom 删除。