关于React中的虚拟DOM与Diff算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于React中的虚拟DOM与Diff算法相关的知识,希望对你有一定的参考价值。

参考技术A React 虚拟DOM:

一个DOM需要数据+模板组合生成,state或props中数据状态变化时,render函数会重新执行即刷新当前DOM,更新页面显示。

第一种是原始的DOM替换,用新的DOM替换旧的DOM,DOM替换或生成都会消耗大量性能。

第二种只替换对比时不同的DOM片段,降低了DOM替换时的性能,但增加了新旧DOM对比这一步骤,性能提升不明显。

第三种

生成真实DOM来显示的同时也生成了一个虚拟DOM,这里虚拟DOM本质即为js对象,用以描述DOM结构。

组成部分为:标签名字,标签属性的集合对象,标签中的元素内容。因div中嵌套span所以这里显示为多层数组。

在虚拟DOM对比时(本质为js对象的对比)消耗了很少的性能,对上面两种方案来说这种提升了极大性能。
优点:

因为DOM节点在安卓ios端无法识别,只能在浏览器识别,但是虚拟DOM可以被识别,生成原生的应用组件,可以在原生应用上显示。
React的Diff算法:

在调用setState方法改变state中的数据状态时,会产生虚拟DOM,为了页面更新提升性能当前的虚拟DOM与旧虚拟DOM发生比较,此时使用了Diff算法。

如果改变state数据次数多频率很高,时间间隔相近,为了提升性能,setState就采用异步的方式,一次性改变状态。

Diff算法比对:

React的虚拟DOM采用的同层比对的方法,对比两个虚拟DOM的每一层,如果遇到不同的情况则下面的层不再进行比对,从最新虚拟DOM的不同的那一层开始,覆盖旧的虚拟DOM,进行替换。

key 循环中的key值比对,比对的是key和value之间的映射关系。

react中的虚拟DOM,jsx,diff算法。让代码更高效

在react中当你的状态发生改变时,并不是所有组件的内容销毁再重建,能复用的就复用

react 组件其实 就是按照层级划分的

找到两棵任意的树之间最小的修改是一个复杂度为 O(n^3) 的问题.

你可以想象, 我们的例子里这不是容易处理的. React 用了一种简单但是强大的技巧, 达到了接近 O(n) 的复杂度. --- diff 算法 (以前是电脑的键盘坏了换一个电脑,现在是键盘坏了直接换键盘) React 仅仅是尝试把树按照层级分解. 这彻底简化了复杂度, 而且也不会失去很多, 因为 Web 应用很少有 component 移动到树的另一个层级去. 它们大部分只是在相邻的子节点之间移动.

例1:(按层级划分)

import React, { Component } from ‘react‘
import MyCom from ‘./MyCom‘;
export default class extends Component {
  constructor (props) {
    super(props);
    this.state = {
      first: true
    }
  }
  changeHandler (event) {
    console.log(event.currentTarget.checked)
    this.setState({
      first: event.currentTarget.checked
    })
  }
  render () {
    if (this.state.first) {
      return (
        <div>
          <h1>diff算法</h1>
          <input type="checkbox" checked={ this.state.first } onChange = { this.changeHandler.bind(this) }/>
          <p>为真我就显示</p>
        </div>
      )
    } else {
      return (
        <div>
          <h1>diff算法</h1>
          <input type="checkbox" onChange = { this.changeHandler.bind(this) }/>
          <p>为假我就显示</p>
        </div>
      )
    }
    
  }
}

例2(利用列表的key)

import React, { Component } from ‘react‘
import MyCom from ‘./MyCom‘;
export default class extends Component {
  constructor (props) {
    super(props);
    this.state = {
      list: [‘aa‘, ‘bb‘, ‘cc‘, ‘dd‘]
    }
  }
  shouldComponentUpdate () {
    // return false
    return true
  }
  addItemnext () {
    let arr = this.state.list
    arr.push(‘eee‘)
    this.setState({
      list: arr
    })
  }
  addItemprev () {
    let arr = this.state.list
    arr.unshift(‘ff‘)
    this.setState({
      list: arr
    })
  }
  addItemcenter () {

  }
  render () {
    return (
      <div>
        <button onClick={ this.addItemnext.bind(this) }>后面加</button>
        <button onClick={ this.addItemprev.bind(this) }>前面加</button>
        <button onClick={ this.addItemcenter.bind(this) }>中间加</button>
        <ul>
          { this.state.list.map((item, index) => {
            return (<li key={item}>{ item }</li>)
          })}
        </ul>
      </div>
    )
  }
}

例3

import React, { Component } from ‘react‘
import MyCom from ‘./MyCom‘;
export default class extends Component {
  constructor (props) {
    super(props);
    this.state = {
      list: [‘aa‘, ‘bb‘, ‘cc‘, ‘dd‘]
    }
  }
  shouldComponentUpdate () {
    // return false
    return true  //要么不写,写的话只可以写true 不然不会更新
  }
  addItemnext () {
    let arr = this.state.list
    arr.push(‘eee‘)
    this.setState({
      list: arr
    })
  }
  addItemprev () {
    let arr = this.state.list
    arr.unshift(‘ff‘)
    this.setState({
      list: arr
    })
  }
  addItemcenter () {

  }
  render () {
    return (
      <div>
        <button onClick={ this.addItemnext.bind(this) }>后面加</button>
        <button onClick={ this.addItemprev.bind(this) }>前面加</button>
        <button onClick={ this.addItemcenter.bind(this) }>中间加</button>
        <ul>
          { this.state.list.map((item, index) => {
            return (<li key={item}>{ item }</li>)
          })}
        </ul>
      </div>
    )
  }
}

 

以上是关于关于React中的虚拟DOM与Diff算法的主要内容,如果未能解决你的问题,请参考以下文章

react虚拟dom与diff算法

React 虚拟dom与diff算法

React diff 算法与其他框架对比

react虚拟dom diff算法

React之DOM的diff算法

react中的虚拟DOM,jsx,diff算法。让代码更高效