React中的虚拟DOM和diff算法

虚拟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去找到他们的映射关系。 在实际中,这通常很容易把刚刚插入的组件从他们当中找出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值