Vue和Rect的比较

[toc]

vue 和 react 在 虚拟dom的diff上,做了哪些改进使 速度更快?

1、传统diff

  计算两颗树形结构差异并进行转换,传统diff算法是这样做的:循环递归每一个节点 。传统diff算法复杂度达到O(n^3 )这意味着1000个节点就要进行数10亿次的比较,这是非常消耗性能的。

2. vue的diff算法

diff算法发生在虚拟dom上,判断是否同一个节点:selector和key都要一样

diff规则:

  1. 只比较同层的节点,不同层不做比较。删除原节点,并且新建插入更新节点(实际开发中很少遇到)
  2. 新旧节点是同层节点,但不是同一个节点,不做精细化比较。删除原节点,并且新建插入更新节点(实际开发中很少遇到)
  3. 新旧节点是同层节点,也是同一个节点,需要做精细化比较

3. react的diff算法

&emsp;&emsp;从左往右依次对比,利用元素的index和标识lastIndex进行比较,如果满足index < lastIndex就移动元素,删除和添加则各自按照规则调整,跨层不比较,同层比较,跟vue一样

diff策略:

  1. 不满足 index < lastIndex 的条件,不移动;满足 index < lastIndex 的条件,移动节点。
  2. 每一次比较都需要重新设置 lastIndex=(index,lastIndex)中的较大数
  3. 移动的节点在前一个被操作的节点后面
  4. 如果从新的节点集合获取的节点在旧节点集合未找到,就是新增,lastIndex为上一次的值不变
  5. 如果新的节点集合遍历完了,旧节点还有值就是删除,loop删除掉就行

4. 对比

相同点:

&emsp;&emsp;Vue和react的diff算法,都是不进行跨层级比较,只做同级比较。

不同点:

  1. Vue进行diff时,调用patch打补丁函数,一边比较一边给真实的DOM打补丁
  2. Vue对比节点,当节点元素类型相同,但是className不同时,认为是不同类型的元素,删除重新创建,而react则认为是同类型节点,进行修改操作
  3. &emsp;&emsp;① Vue的列表比对,采用从两端到中间的方式,旧集合和新集合两端各存在两个指针,两两进行比较,如果匹配上了就按照新集合去调整旧集合,每次对比结束后,指针向队列中间移动;

    &emsp;&emsp;②而react则是从左往右依次对比,利用元素的index和标识lastIndex进行比较,如果满足index < lastIndex就移动元素,删除和添加则各自按照规则调整;

    &emsp;&emsp;③当一个集合把最后一个节点移动到最前面,react会把前面的节点依次向后移动,而Vue只会把最后一个节点放在最前面,这样的操作来看,Vue的diff性能是高于react的

vue 和 react 里的key的作用是什么? 为什么不能用Index?用了会怎样? 如果不加key会怎样?

1.什么是key

key是虚拟Dom对象的标识,在更新显示时key起着极其重要的作用。

2.key的作用

当Vue中data或React中state的数据发生变化时,react会根据新数据生成新的虚拟Dom,随后Vue/React会对「新虚拟Dom」和「旧虚拟Dom」进行diff比较,比较规则如下:

  1. 旧虚拟Dom中找到与新虚拟Dom相同的key:
  • 若虚拟Dom中的内容没变,则直接使用之前的真实Dom
  • 若虚拟Dom中的内容变了,则生成新的真实Dom,随后替换掉页面中之前的真实Dom
  1. 旧虚拟Dom中没有找到与新虚拟Dom相同的key:
  • 根据数据创建新的真实Dom,随后渲染到页面

3.为什么遍历列表时,key最好不要用index

用index作为key,可能引发的问题如下:

  1. 若对数据进行逆序添加,逆序删除等破坏顺序的操作,会产生虚拟DOM和旧的真实DOM中的部分key(甚至所有Key)都对不上的问题,接着会产生很多没有必要的真实DOM更新,渲染效率低下。
  2. 如果列表行结构中还包含输入类的DOM,则会产生错误的DOM更新,使得界面出现问题
  3. 如果只是数据单纯的展示,不做增删改,使用index也没关系

4.如果不加key会怎样?

  1. 当不带Key的时候,采用的是遍历的方式来对比新旧节点,从而达到更新节点的效果。
  2. 带key的时候使用的是map映射来更新节点。
  3. 在模板简单的时候使用就地复用(就是不使用key)效率会更高。
  4. 所以使用key并不意味着一定可以提高diff算法的效率。
  5. key的作用主要是为每个节点设置一个唯一的标识,可以更快,更准确的拿到节点。
  6. 在一些情况下,还可以避免就地复用带来的副作用(表单数据错位)