React学习_03_虚拟DOM和key属性
本节内容:
1. 算法复杂度O(n)
2. 虚拟DOM计算diff的流程
3. key属性的作用
JSX运行的基础:Virtual DOM
React组件在内部维护了一套虚拟DOM的状态,这套虚拟的DOM状态是被映射到真实DOM上的,当虚拟DOM的状态发变化的时候,会去计算变化前后虚拟DOM的区别,从而计算一个Diff,最终在渲染真实DOM的时候,会根据Diff高效的局部修改发生改变的DOM节点,而不会刷新整个DOM树。
React计算变化前后虚拟DOM的区别: 广度优先分层比较(拿到变化前后两个虚拟DOM结构之后,会逐层比较)
1. 节点属性/顺序发生变化(属性变化则修改原节点属性, 同层内节点顺序变化则交互节点顺序)
【示例】节点A和节点B顺序发生改变,则将节点A及其子节点树 与 节点B及其子节点树 整体进行交换。
2. 节点类型变化(会直接删除原来的节点(F), 然后创建一个新的节点(G))
【注意】删除原节点的时候,React不会去检查原节点(F)在新的虚拟DOM的其他分层中是否有出现,算法只会关注本层,原节点即使是被推倒了其他层,React会在比对那一层的时候进行创建。
3. 节点跨层移动(Diff算法会将跨层的节点进行删除,然后再在出现的层进行节点创建)
【示例】节点D由第3层移动到了第4层,Diff在比对第3层的时候,会首先将D节点及其子节点树全部删除掉,在比对到第4层的时候,会创建一个新的节点D及其整个子节点树。
React的Diff算法分析:
UI的特点是整个DOM树的结构是相对稳定的,第3种情况节点跨层移动发生的是比较少的,最多的是前两种,放弃第三种情况的优化,可以整体提高Diff算法的性能,使得n个节点的DOM树的Diff的算法复杂度为O(n)。
虚拟DOM的两个假设:
1. 组件的DOM结构是相对稳定的
2. 类型相同的节点可以背唯一标示(相同的div节点可以被区分)
【说明】React是通过节点的key来唯一标示节点的,要是不指定key,React会发出一个warning,并且在计算虚拟DOM的时候,React也不会进行类似情况1的节点的修改/交换,而是进行开销更大的节点删除/创建;因此指定节点的key,可以提高DOM绘制的性能。