美文网首页
四:React进阶二 (虚拟DOM)

四:React进阶二 (虚拟DOM)

作者: 废柴阿W | 来源:发表于2018-12-30 09:17 被阅读0次

    扩展:深入Vue2.x的虚拟DOM diff原理

    第一种渲染

      1. state 数据
      2. JSX 模板
      3. 数据 + 模板 结合 , 生成真实的DOM,来显示
      4. state 发生改变
      5. 数据 + 模板 结合 , 生成真实的DOM,替换原始的DOM
    
    缺陷:
    第一次生成了一个完整的DOM片段
    第二次生成了一个完整的DOM片段
    第二次的DOM替换第一次的DOM,非常耗性能
    
    
    

    第二种渲染

      1. state 数据
      2. JSX 模板
      3. 数据 + 模板 结合 , 生成真实的DOM,来显示
      4. state 发生改变
    *****************************
      5. 数据 + 模板 结合 , 生成真实的DOM,并不直接替换原始的DOM
      6. 新的DOM(DoucumentFragment(文档碎片)) 和原始的DOM 做比对, 找差异
      7. 找出input 框发生了变化
      8. 只用新的DOM 中的input元素,替换掉老的DOM中的input元素
    
    注:DoucumentFragment(文档碎片):还在内存里,还没有挂载到页面
    
    缺陷:
    性能的提升并不明显
    

    第三种渲染

      1. state 数据
      2. JSX 模板
      3. 数据 + 模板 结合 , 生成真实的DOM,来显示
    <div id='abc'> <span> hello world </span> </div>
    **********************
      4. 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实DOM)(损耗了性能)
    ['div',{id:'abc},['span',{},'hello world']]
      5. state 发生变化
      6. 数据+ 模板生成新的虚拟DOM (极大的提升了性能)
    ['div',{id:'abc},['span',{},'bye bye']]
      7. 比较原始虚拟DOM 和新的虚拟DOM的区别,找到区别是span中内容 (极大的提升了性能)
      8. 直接操作DOM , 改变span中的内容
    

    损耗比较:JS创建一个JS对象,远比JS创建一个DOM元素损耗要小,因为JS创建DOM的时候需要调用web application级别的一个api

    引入虚拟DOM能提高性能原理:减少了真实DOM 的创建和JS DOM的对比,而是去创建JS对象和对比JS对象

    实际上:

      1. state 数据
      2. JSX 模板
      3. 数据 + 模板 , 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实DOM)(损耗了性能)
      ['div',{id:'abc},['span',{},'hello world']]
      4. 用虚拟DOM的结构生成真实的DOM , 来显示
    <div id='abc'> <span> hello world </span> </div>
      5. state 发生变化
      6. 数据+ 模板 生成新的虚拟DOM  (极大的提升了性能)
    ['div',{id:'abc},['span',{},'bye bye']]
      7. 比较原始虚拟DOM 和新的虚拟DOM的区别,找到区别是span中内容 (极大的提升了性能)
      8. 直接操作DOM , 改变span中的内容
    
    优点:
    1.性能提升了
    2. 它使得跨端应用得以实现。React Native
    

    render函数中:JSX → createElement → 虚拟 DOM(JS 对象)→ 真实的 DOM

    虚拟DOM的diff算法

    • setState是个异步函数,是为了提高react底层性能


    React中如果在短时间内(例如一个函数体里)连续执行了三次setState操作,React会把三次setState合并成一次setState,只进行一次虚拟DOM的diff比对,最后只更新一次DOM。

    • 同层比对


    • React的diff算法核心:同级比较,一比较一层,有差异整体替换。diff算从虚拟DOM树的根节点进行比较,如果根节点就存在差异,就不会再比较下层节点,则会把原虚拟DOM该层节点下的DOM全部删除,用新的虚拟DOM重新生成一遍页面上绑定的虚拟DOM,再用页面绑定的虚拟DOM重新生成页面上的真实DOM。
    • diff算法,同层比对,算法简单,则比对速度很快。所以虽然会浪费DOM渲染的性能,但是它可以大大减少了两个虚拟DOM比对上花费的性能消耗。
    • diff过程


    • key值的作用


    • 例子:一个虚拟DOM上的数组结构做循环,渲染到了页面上。在没有key值时,数据发生变化后,diff算法没法确定新虚拟DOM和原虚拟DOM元素间的关系,好比新的a变了,对应老的a到底是数组中的哪个元素呢?diff算法只能写双循环遍历确定,这样就会造成很大的性能开销。而假如,在对虚拟DOM数组做循环时给每个最外层父节点设置key值取名字后,新a变化后立马就能抓到对应老a来对比,好的,你变化,那么把a这个节点树整颗替换即可,再例如数组push了新元素z,diff算法一看key,原来没它,就生成新DOM树即可。
    • 实例:循环是用index做key值。例如['a','b', 'c'],循环拿index做key值,当我们删除a时,新数组对应的就是 ['b':0, 'c': 1],好的diff算法一上来看到key值,怎么“全变了”,好吧,没办法,只能去重新这棵节点数!而当我们用稳定的唯一值做key值时,删除a元素后,diff算法比较后只会把dom树上的a节点删除,节省了渲染的性能。

    相关文章

      网友评论

          本文标题:四:React进阶二 (虚拟DOM)

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