React中的虚拟DOM和diff算法

版权声明:转载请注明出处 https://blog.csdn.net/qq799028706/article/details/88076661

虚拟DOM

React原理

我们来想一下如何实现React

第一种方案:

1. state 数据
2. JSX 模板
3. 数据 + 模板 结合, 生成真实的DOM, 来显示
4. state 发生改变
5. 数据 + 模板 结合, 生成真实的DOM, 替换原始的DOM

但这种方案在第五步有着很大的性能缺陷
用新生成的DOM去替换原始的DOM, 非常消耗性能

第二种方案

1. state 数据
2. JSX 模板
3. 数据 + 模板 结合, 生成真实的DOM, 来显示
4. state 发生改变
5. 数据 + 模板 结合, 生成真实的DOM, 并不直接替换原始的DOM
6. 新的DOM (DocumentFragment) 和原始的DOM 做比对,找差异
7. 找出有差异的DOM元素
8. 将有差异的DOM元素替换掉旧的DOM元素

这种方案同样存在缺陷
关键在于第六步,我们找新DOM和原始DOM的比对找差异过程中,也很消耗性能,性能提升并不明显

第三种方案:虚拟DOM

1. state 数据
2. JSX 模板
3. 生成虚拟DOM(JS对象), 用js对象描述dom信息
    {
        tag: 'div',
        attrs: {id: 'root'},
        children: [
            {
                tag: 'p',
                children: ['hello, world']
            }
        ]
    }
4. 借助虚拟DOM, 生成真实的DOM, 来显示
    <div id='root'><p>hello, world</p></div>
5. state 发生改变
6. 生成新的虚拟DOM
7. 比较原始虚拟DOM和新的虚拟DOM的差异
8. 直接操作DOM,改变有差异的内容

优点:生成 js 对象很快, 所以在两个js对象中找差异 损耗性能很小
极大的提升了性能

diff算法

diff算法用于比较虚拟dom之间的差异

1. 逐级比较

diff算法通过逐级的去比较两颗节点树的差异,大大降低了复杂性

2. 列表List

假设我们有一个组件,它在一个迭代中渲染了5个组件,而下一次渲染的时候在组件列表的中间插入一个新的组件。 只是通过这个信息真的很难知道如何在两个组件列表之间进行映射。
默认情况下,React将先前列表的第一个组件与下一个列表的第一个组件相关联,等等。您可以提供一个Key属性,以帮助React去找到他们的映射关系。 在实际中,这通常很容易把刚刚插入的组件从他们当中找出来。

猜你喜欢

转载自blog.csdn.net/qq799028706/article/details/88076661