简述
传统diff两棵树的算法时间复杂度很高,是O(n^3),Vue与React都对它们的diff算法做了优化。
Vue diff
开始比较
- 比较父节点是同一节点的那一层子节点
- 最大的根节点一开始可以直接比较
比较流程
- 先找到不需要移动的相同节点
- 再找到需要移动的相同节点
- 最后找不到,删除新建一个节点
修改DOM树
这里会存在三棵树,一颗页面DOM树,一颗是旧的VNode树,一颗是新的VNode树。页面DOM 树和旧VNode 树 节点一一对应的。进行比较的过程中不会对这两棵Vode树进行修改,而是以比较的结果直接对真实DOM进行修改
React diff
diff策略
- Web UI 中 DOM 节点跨层级的移动操作特别少,可以忽略不计。
- 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
- 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分。
React的diff分为tree diff、component diff、element diff
tree diff
对树进行分层比较,两棵树只会对同一层次的节点进行比较。即比较同一个父节点下的所有子节点。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。
component diff
- 如果是同一类型的组件,则与tree diff一样
- 如果类型不同,则替换组件下的所有子节点
element diff
当比较处于同一层级时,React提供了三种操作
- 插入,即插入新节点
- 移动,位置不同但是可以复用的节点则移动
- 删除,不能复用或者不存在,则删除