深入了解react中的虚拟DOM

292 阅读2分钟

在react中,数据更新会驱动页面重新渲染,假设没有react,要我们自己去实现这个功能,我们会怎么做呢?

最简单的思路是这样的:

  • state数据
  • JSX模板
  • 数据+模板,生成真实的DOM来显示
  • state发生改变
  • 数据+模板,生成真实的DOM,替换原始的DOM

但是这样的方案有个致命的缺陷:

  • 第三步和第五步,非常耗性能,

那么如何做性能优化呢?结合实际开发经验,我们知道,很多时候,往往只是一部分DOM发生了改变,而不是整个,所以很自然的就能想到,在上一个方案中,我们缺少了一步对比DOM,只找出变化的DOM进行替换不就好了吗?

  • state数据
  • JSX模板
  • 数据+模板,生成真实的DOM
  • state改变
  • 数据+模板,生成真实的DOM,对比原始的DOM
  • 找出变化的DOM部分进行替换

改进的方案看似对第一种方案进行了优化,但实际上看第五步,生成真实的DOM,对比原始的DOM这一步依然很耗性能,相当于没优化。

接下来了解下react是如何进行优化的:

  • state数据
  • JSX模板
  • 根据数据+模板,生成虚拟DOM(虚拟DOM就是一个用来描述真实DOM的JS对象)
  • 用虚拟DOM的结构生成真实的DOM
  • state改变
  • 生成新的虚拟DOM,对比原始的虚拟DOM,找出变化的部分
  • 直接操作DOM,改变变化部分的内容

在react的方案中,第六步极大的提升了性能,毕竟对比两个JS对象,要比对比两个DOM合适得多。

所以我们平时写的JSX,实际上就是一个模板,加上数据,生成了虚拟DOM,然后在生成真实的DOM。

在react底层,会将我们写的JSX,通过createElement()方法,转换成虚拟DOM(也就是js对象),然后生成真实DOM。

class App extends Component {
    render() {
        return (
            <!--<div id="div1">123</div>-->
            React.createElement('div', {id: 'div1'}, '123')
        )
    }
}

上述代码,与直接return出去一个div是一样的效果。