React中的算法和数据结构
深度优先搜索、递归、动态规划、散列表、数组、链表、二叉树、堆、栈
Vue中的算法和数据结构
动态规划、递归、二分查找、散列表、LRU(最近最少使用)、数组
Vue diff
数据结构
- 两个vdom数组
条件
两个指针,一个指向第一位、一个指向最后一位- 存在
两个vdom数组,一个是老的vdom,一个是新的vdom
流程
从前往后找,比较两个节点,如果节点不能复用,停止从后往前找,比较两个节点,如果节点不能复用,则停止- 如果老节点没有了,剩余的新节点都是新增的
- 如果新节点没有了,剩余的老节点都是需要删除的
- 如果新老节点都有
- 为了方便接下来的查找,把
新节点做成key:index的Map图 - 遍历老节点数组(剩余部分),根据key属性在Map中查找,如果能找到,表示这个节点是可以被复用的。
React diff
比较的是key和tag
数据结构
- 新vdom是
数组,也就是newChildren,老vdom是fiber单链表,也就是oldFiber
条件
一个指针- 新旧两个单向Fiber链表(初次渲染阶段没有老链表)
流程
- 新老VDOM都是
从左边开始遍历的,按位置比较,即第i个老vdom和第i个新vdom比较,如果节点可以复用,那么先复用,然后新老vdom都往后移一位,否则就中止本轮循环。 - 如果经过step1,新节点已经遍历完了,那么如果还有剩下的老节点,删除即可。
- 如果经过step1,老节点没了,新节点还有,那么新节点逐个新增即可。初次渲染走的就是这里。
- 走到现在,新老节点都还有,但是是乱序的。因此可以把
oldFiber单链表做成Map(key:Fiber),即existingChildren,接下来遍历newChildren,找到能复用的fiber,就复用并且从existingChildren删除这个fiber。 - 经历过step4之后,发现老节点existingChildren中还有没被复用的,全部删除即可
区别
数据结构不同
- vue:
数组 - React:Fiber的
单链表,所以无法反向遍历,如果设计成双链表,但是空间上会多一倍
比较过程不同
- vue:是从前往后,然后重后往前
- React:只有从前往后的过程
临时存储Map不同
- vue:使用map进行存储是 key:
index,存储的是新节点数组 - React:map存储是 key:
Fiber,存储的是旧链表