(精华)2020年7月31日 React 虚拟dom的渲染机制和性能调优
【摘要】
//-------------------------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就会 移动元素
// 而不是将他们直接删除 然后再生成
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
删除主键性能调优
<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
高阶组件
export default High(Home)
const app=High(Home)
class Home extends React.Component{
render(){
return(
// High(Home) 引用关系重新渲染不能在内部使用
app
)
}
}
文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。
原文链接:codeboy.blog.csdn.net/article/details/107704471
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)