React中的虚拟DOM

我们知道,当组件的state和props发生变化的时候,render函数就会重新执行,组件就会被重新渲染,这样是性能非常低的。因此,react引入了虚拟DOM.

虚拟DOM是什么呢?虚拟DOM就是一个JS对象,用它来描述真实DOM。

当state发生变化时,render函数会重新执行渲染页面。如果我们自己来做这个功能,那该怎样实现呢?

方案一:
1. 定义一个state,先有数据
2. 有一个模板(render函数中jsx的代码)
3. 数据与模板相结合,生成真实的DOM来显示
4. state发生改变
5. 数据与模板结合,生成真实DOM,替换原始的DOM

缺陷:
第一次生成了完整的DOM片段
第二次生成了完整的DOM片段
第二次的DOM替换第一次的DOM,非常耗性能

有时候我们只是改了页面上一小部分数据,这种方案下,却要替换整个DOM,性能很低。

方案二:
1. 定义一个state,先有数据
2. 有一个模板(render函数中jsx的代码)
3. 数据与模板相结合,生成真实的DOM来显示
4. state发生改变
5. 数据与模板结合,生成真实DOM,并不直接替换原始的DOM
6. 新的DOM(也就是DocumentFragment)和原始的DOM作比对,找差异
7. 找出input框发生了变化
8. 只用新的DOM中的input元素,替换掉旧的DOM中的input元素

缺陷:
虽然只替换发生了变化的input元素,提升了性能,但是在新旧DOM比对过程中也消耗了性能,因此性能提升的并不明显
方案三:
1. 定义一个state,先有数据
2. 有一个模板(render函数中jsx的代码)
3. 数据与模板相结合,生成真实的DOM来显示
例如真实的DOM:<div id='abc'><span>hello~</span></div>
4. 生成虚拟DOM
虚拟DOM:['div', {id:'abc'}, ['span', {}, 'hello~']]
5. state发生变化
6. 生成新的虚拟DOM
虚拟DOM:['div', {id:'abc'}, ['span', {}, 'bye~']]
7. 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容
8. 直接操作DOM,改变span中的内容

减少了真实DOM的创建以及对比,我们创建和对比的都是JS对象,这样提升了极大的性能。

实际上,react底层真正的实现:

1. 定义一个state,先有数据

2. 有一个模板(render函数中jsx的代码)

3. 生成虚拟DOM
虚拟DOM:['div', {id:'abc'}, ['span', {}, 'hello~']]

4. 用虚拟DOM的结构生成真实的DOM来显示
真实的DOM:<div id='abc'><span>hello~</span></div>

5. state发生变化

6. 生成新的虚拟DOM
虚拟DOM:['div', {id:'abc'}, ['span', {}, 'bye~']]

7. 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容

8. 直接操作DOM,改变span中的内容

当有了数据、JSX模板之后,react会先生成虚拟DOM,后依据虚拟DOM生成真实DOM。
JSX代码与真实的DOM之间的关系:先将JSX代码变成JS对象(react底层把JSX代码通过creatElement方法将其变成JS对象),再转化成真实的DOM

虚拟DOM的优点:

1. 提升了性能

2. 使得跨端应用得以实现。React Native

 

posted @ 2019-07-22 16:14  糖小圆  阅读(563)  评论(0编辑  收藏  举报