React的虚拟 DOM 和 Diff 算法
页面渲染
执行步骤:
-
初次渲染的时候,React 根据 state ,创建一个 虚拟 DOM 对象
-
虚拟 DOM 对象再通过 render 生成真实 DOM ,渲染到页面中
-
当数据发生变化后,会重新渲染新的数据,创建新的虚拟 DOM 对象
-
新旧虚拟 DOM 通过 Diff 算法进行对比,得到需要更新的内容
-
最后将需要更新的地方更新到真实 DOM 中,其他不变,然后渲染到页面中
虚拟DOM
虚拟DOM:本质上就是一个 JS 对象,用来描述渲染在页面上的内容(UI结构)
react DOM 更新策略: React 会自顶向下一项一项进行 Diff 。就是在组件状态发生变化时,组件树就会自顶向下一项一项对应的进行对比
Diff 算法
React 中对普通的 Diff 算法进行了三大优化
-
tree diff --- 层级对比
- 重点就是:进行同层对比。就是进行节点比较的时候,不会跨层去比较。相当于当这层没有相同的节点的话,就算其它层有相同的话,那也是不行的。这层的这个节点还是会被删除掉。
例:下图在进行对比的时候,第一层之间进行对比,第二层之间进行对比。不会跨层进行对比。
-
component diff --- 组件对比
-
遇到组件对比时:
-
若是统一类型的组件,两组件的虚拟 DOM 没有任何变化时, 手动通过 shouldComponentUpdate 进行判断是否需要进行 diff。
-
若是同一类型的组件,两组件的虚拟 DOM 发生变化时,直接进行 层级对比 就可以。
-
若是不同类型的组件,直接将这个不同的组件判断为 dirty component (脏组件) ,直接替换掉该组件及其之下的所有子组件。
-
-
-
element diff ---节点对比
-
遇到节点对比时:
-
若有新节点的话,直接执行插入操作
-
若有多余的节点,直接进行删除操作
-
若是换位的节点,通过双方节点的 唯一 key 值进行比对,看对应 key 值的元素是否发生变化。如果没有发生变化的话,直接进行节点的移动就可以。如果发生变化,那就更改节点元素再进行下一步操作。
-
-