Vue和Rect的比较
2023-02-20
次访问
Vue和Rect的比较
[toc]
vue 和 react 在 虚拟dom的diff上,做了哪些改进使 速度更快?
1、传统diff
  计算两颗树形结构差异并进行转换,传统diff算法是这样做的:循环递归每一个节点 。传统diff算法复杂度达到O(n^3 )这意味着1000个节点就要进行数10亿次的比较,这是非常消耗性能的。
2. vue的diff算法
diff算法发生在虚拟dom上,判断是否同一个节点:selector和key都要一样
diff规则:
- 只比较同层的节点,不同层不做比较。删除原节点,并且新建插入更新节点(实际开发中很少遇到)
- 新旧节点是同层节点,但不是同一个节点,不做精细化比较。删除原节点,并且新建插入更新节点(实际开发中很少遇到)
- 新旧节点是同层节点,也是同一个节点,需要做精细化比较
3. react的diff算法
  从左往右依次对比,利用元素的index和标识lastIndex进行比较,如果满足index < lastIndex就移动元素,删除和添加则各自按照规则调整,跨层不比较,同层比较,跟vue一样
diff策略:
- 不满足 index < lastIndex 的条件,不移动;满足 index < lastIndex 的条件,移动节点。
- 每一次比较都需要重新设置 lastIndex=(index,lastIndex)中的较大数
- 移动的节点在前一个被操作的节点后面
- 如果从新的节点集合获取的节点在旧节点集合未找到,就是新增,lastIndex为上一次的值不变
- 如果新的节点集合遍历完了,旧节点还有值就是删除,loop删除掉就行
4. 对比
相同点:
  Vue和react的diff算法,都是不进行跨层级比较,只做同级比较。
不同点:
- Vue进行diff时,调用patch打补丁函数,一边比较一边给真实的DOM打补丁
- Vue对比节点,当节点元素类型相同,但是className不同时,认为是不同类型的元素,删除重新创建,而react则认为是同类型节点,进行修改操作
-   ① Vue的列表比对,采用从两端到中间的方式,旧集合和新集合两端各存在两个指针,两两进行比较,如果匹配上了就按照新集合去调整旧集合,每次对比结束后,指针向队列中间移动;
  ②而react则是从左往右依次对比,利用元素的index和标识lastIndex进行比较,如果满足index < lastIndex就移动元素,删除和添加则各自按照规则调整;
  ③当一个集合把最后一个节点移动到最前面,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比较,比较规则如下:
- 旧虚拟Dom中找到与新虚拟Dom相同的key:
- 若虚拟Dom中的内容没变,则直接使用之前的真实Dom
- 若虚拟Dom中的内容变了,则生成新的真实Dom,随后替换掉页面中之前的真实Dom
- 旧虚拟Dom中没有找到与新虚拟Dom相同的key:
- 根据数据创建新的真实Dom,随后渲染到页面
3.为什么遍历列表时,key最好不要用index
用index作为key,可能引发的问题如下:
- 若对数据进行逆序添加,逆序删除等破坏顺序的操作,会产生虚拟DOM和旧的真实DOM中的部分key(甚至所有Key)都对不上的问题,接着会产生很多没有必要的真实DOM更新,渲染效率低下。
- 如果列表行结构中还包含输入类的DOM,则会产生错误的DOM更新,使得界面出现问题
- 如果只是数据单纯的展示,不做增删改,使用index也没关系
4.如果不加key会怎样?
- 当不带Key的时候,采用的是遍历的方式来对比新旧节点,从而达到更新节点的效果。
- 带key的时候使用的是map映射来更新节点。
- 在模板简单的时候使用就地复用(就是不使用key)效率会更高。
- 所以使用key并不意味着一定可以提高diff算法的效率。
- key的作用主要是为每个节点设置一个唯一的标识,可以更快,更准确的拿到节点。
- 在一些情况下,还可以避免就地复用带来的副作用(表单数据错位)
