虚拟DOM

作者: sweetBoy_9126 | 来源:发表于2020-02-25 15:23 被阅读0次
render() {
  return (
    <div>
        <label>输入内容</label>
        <input value={this.state.inputValue}/>
        <button onClick={this.handleBtnClick}>提交</button>
        <Test content={this.state.inputValue}/>
    </div>
  )
}

实现react中render的几种方案(数据更新视图)

方案一:

  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 结合,生成真实的DOM来显示
  4. state 发生改变
  5. 数据 + 模板 结合,生成真实的DOM,替换原始的DOM
    缺陷:
    每一次只要有一个state发生改变,都会生成一个新的完整的DOM片段来替换旧的,非常消耗内存(而实际上我们修改某一个state只需要依赖他的DOM元素被替换)

方案二:

  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 结合,生成真实的DOM,来显示
  4. state 发生改变
  5. 数据 + 模板 结合, 生成真实的DOM,并不是直接替换原来的DOM
  6. 新的DOM 和 原始的DOM 作对比,找差异
  7. 找出依赖了变化的state的DOM元素
  8. 只用新的相关变化的元素,替换调老的DOM中的对应元素即可
    缺陷:相比方案一虽然DOM替换的内容变少了,性能有所提升,但是又损耗了新的DOM与原始DOM对比的性能,所以性能提升并不明显。

方案三:

  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 结合 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实的DOM)(生成js对象和真实DOM相比,性能损耗极小)
// 第一个元素是标签名,第二个是属性,第三个是它的子元素
['div', {id: 'abc'}, ['span', {}, 'hello world']]
  1. 用上面虚拟DOM的结构生成真实的DOM,来显示
<div id="abc"><span>hello world</span></div>
  1. state 发生变化
  2. 数据 + 模板 生成新的虚拟DOM (极大地提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye bye']]
  1. 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容变了(极大地提升了性能)
  2. 直接操作DOM,改变span中的内容

所以render的过程其实就是JSX -> createElement -> 虚拟DOM(JS对象)-> 真实DOM

虚拟DOM的好处

  1. 性能提升了(DOM比对变成了JS对象的比对)
  2. 使得跨段应用得以实现。React Native(因为如果没有虚拟DOM直接生成DOM在原生app里是不支持的,而js对象是支持的,可以转为原生的组件)

虚拟DOM中的Diff算法

-同层比对
如上图左右两边都是虚拟DOM,它会先比较第一级,如果相同再继续下一级,如果不同直接删除当前级别下的所有子节点的DOM,重新生成一遍当前节点下的所有DOM,然后用重新生成的DOM替换原始页面的DOM;
优点算法简单,比对的速度非常快;
缺点可能造成DOM节点上渲染的浪费;

  • key值比对
    列表循环的时候使用key值,为了提高虚拟DOM的比对性能,新旧虚拟DOM可以通过key值建立联系,所以key值要保持稳定,在项目中能不用index就不用index(如果使用index,比如有a,b,c三个那分别对应的索引就是0,1,2,可如果把a删了,b,c就分别对应0,1和之前的key值就对应不起来)

相关文章

网友评论

      本文标题:虚拟DOM

      本文链接:https://www.haomeiwen.com/subject/pdrtchtx.html