React 渲染机制
2020-04-30 本文已影响0人
行走的蛋白质
React 渲染过程
- 在使用 React 构建应用时,总有一个步骤是将组件 / 虚拟 DOM 树渲染到真实的 DOM 上,将任务交给浏览器进而进行 Layout 和 Paint 等步骤,这个函数就是 React.render()
- React 整个渲染机制就是 React 会调用 Render 函数构建一颗 DOM 树
- 在 state / props 发生改变的时候,render 函数会被再次调用重新渲染所有的节点,构造出新的虚拟 DOM 树,然后跟原来的 DOM 树用 diff 算法进行比较,找到最小化的差异并批量改动,再渲染到真实的 DOM 上,这样做可以减少频繁的 DOM 操作,从而提升性能。
React diff 算法说明
- 在 React 中,两颗 DOM 树只会对同一层的节点进行比较,若发现节点已经不存在,该节点以及其子节点都会被删除不会用于进一步的比较。这样只需要对树进行一次的遍历,就能完成整个 DOM 树的比较
- 对于同层节点,数组遍历的增减关键字是 key,若节点本身完全相同 ( 类型相同、属性相同 ) 只是位置不同,则 React 只需要考虑同层节点的位置变换,不需要进行节点的销毁和重新创建。
- 对于不同层级的节点只能是销毁和重新创建
diff 算法分情况
节点类型不同
- 在树中的同一位置更新前后节点类型不同,React 会直接删除原节点,然后创建并插入新的节点
- 删除节点即彻底销毁该节点,也就是说后续不会查找是否有另外一个节点等同于删除的该节点,如果删除的该节点有子节点,那么子节点也会被删除。这也是 diff 算法复杂度能够降低到 O(n) 的原因
- 同理,当树的同一位置遇到更新前后不同的组件时,也是销毁原组件,把新的组件加上去。这应用了第一个假设,不同的组件一般会产生不同的 DOM 结构,与其浪费时间去比较不同的 DOM 结构不如完全创建一个新的组件加上去。
- 节点类型相同但是属性不同
- React 会对属性进行重设,从而实现节点的转换
- 节点类型相同且属性相同
- 对于同层节点,若节点本身完全相同 ( 类型相同且属性相同 ) 只是位置不同,则 React 只需要考虑同层节点的位置变换,不需要进行节点的销毁和重新创建,这就需要用到 key 属性
- 对于不同层的节点,即使节点本身完全相同 ( 类型相同且属性相同 ) 也只能是销毁并重新创建
-
key 属性
- 帮助 React 定位到正确的节点并进行比较,从而大幅减少 DOM 操作的次数,提高性能