(精华)2020年7月31日 React 虚拟dom的渲染机制和性能调优

举报
愚公搬代码 发表于 2021/10/18 22:55:38 2021/10/18
【摘要】 //-------------------------1----------------------------- function Table ({rows}) { return...
//-------------------------1-----------------------------
    function Table ({rows}) {
        return (
            <table>
                {
                    rows.map(row=>(
                        <tr>
                            <td key={row.id}>{row.title}</td>    
                        </tr>
                    ))
                }    
            </table>
        )
    }
    <Table rows={rows}/>

    var rows = [{id:1,title:'第一的标题'}]

    ReactDOM.render(
        React.createElement(Table,{rows:rows}),
    
    document.getElementById('root'))

//-------------------------2-----------------------------
    var str = <div className="cn">
        content
    </div>
    var str = React.createElement('div',{className:'cn'},'content')
//-------------------------3-----------------------------
    {
        type:'div',
        props:{
            className:'cn',
            chilldren:[
                'content1'
            ]
        }
    }
//-------------------------4-----------------------------
    var com1 = <div className="cn" children={[<div>content1</div>,<p>content2</p>]}></div>

    
     ReactDOM.render(
        com1,
    
    document.getElementById('root'))
//----------------------------------
// 1 如果type是一个string类型的标签名称 创建一个标签 附带上props下的所有attributes
    // 2 如果type是一个(function)(class) 调用它的时候 会对这个结果递归重复这个过程
    // 3 如果props下面有children属性 在父节点下重复以上的过程
//-------------------------------------------------------------------------
// render通常在根节点调用一次 后续的更新会有state来控制,要提高react性能从setstate下手
    // 在更新的时候 react将调用diff算法 
    // 场景1 type是一个字符串 type保持不变 props也保持不变
    // 更新前
    // {type:'div',props:{className:'cn'}}
    // 更新之后
    // {type:'div',props:{className:'cn'}} 这一种是最简单的情况 DOM保持不变

    // 场景2 type是一个字符串 type保持不变 props是不同的
    // 更新前
    // {type:'div',props:{className:'cn'}}
    // 更新之后
    // {type:'div',props:{className:'cnn'}}
    // 不会删除一个节点 而是直接改变props

    //  场景3 type已经改变成不同的string
    // 更新前
    // {type:'div',props:{className:'cn'}}
    // 更新之后
    // {type:'span',props:{className:'cn'}}
    
    // 甚至都不会尝试更新 直接删除掉 会删除掉所有的子节点 
    // 比较type 是通过 === 

    // 场景4 type是一个 component
    // 更新前
    // {type:Table,props:{rows}}
    // 更新后
    // {type:Table,props:{rows}}
    // 会对组件进行遍历和扫描 
//---------------------------------------------------------------------
props:{
        children:[
            {type:'div',key:'div'},
            {type:'span',key:'span'},
            {type:'br',key:'br'}
        ]
    }

    props:{
        children:[
            {type:'span',key:'span'},
            {type:'br',key:'br'},
            {type:'div',key:'div'}
        ]
    }

    // 不含key的组件顺序不同会全部重新删除渲染
    // 一旦元素有一个key属性 将会按照key 而不是 index来比较 是要key是唯一的 react就会 移动元素
    // 而不是将他们直接删除 然后再生成


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

diff算法

+ domdiff算法解析
    + diff策略
        - dom节点跨层级的操作比较少
        - 拥有相同类的两个组件会生成相似的树形结构 不同的类组件会生成不同的树形结构
        - 同一层级的一组子节点 可以通过uuid进行区分
    + diff 粒度
        + tree diff 
            - 对树的每一层进行遍历 如果组件不存在了 会直接删除
        + Component diff
            - 同一类型的组件 继续比较下去 是否需要比较 -> shouldComponentUpdate
            - 不同类型的组件 直接替换
        + Element diff
            - 常见的类型就是列表
            - 比较策略就是 uuid 遍历一遍 确定要删除的和要更新的
            - uuid一般不要设置成数组的index

ReactElement 用来承载信息的容器 
1. type 类型 用于判断如何创建节点
2. key 和 ref 
3. props 新的属性内容
4. $$typeof 用于确定是否属于 ReactElement


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

删除主键性能调优


    <div>
        <Message />,    
        <Table />,    
        <Footer />,    
    </div>

    {
        props:{
            children:[
                {type:Message},
                {type:Table},
                {type:Footer},
            ]
        }
    }
    // 要把Message组件 删除掉  短路表达式is <Message />

    // React.PureComponent  React.Component
    // 实施了一层浅的比较 shouldComponentUpdate 实施了一个浅的比较 
    // 浅的比较 props state 不是免费的 甚至于对大多数组件都是不值得的
    // 经验总结 : pureComponent 往往适用于 复杂的表单和表格 
    // 越简单越不建议使用pureComponent


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

高阶组件

export default High(Home)
const app=High(Home)
class Home extends React.Component{
  render(){
    return(
      // High(Home)  引用关系重新渲染不能在内部使用
      app
    )
  }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。

原文链接:codeboy.blog.csdn.net/article/details/107704471

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。