目录
- 1. diff算法
-
-
-
- 1.1 diff 算法的作用
- 1.2 reconcilition(调和)
- 1.3 diff算法优化
- 1.4 tree diff
- 1.5 component diff
- 1.6 element diff
-
-
- 2. Component、PureComponent和Immutable
-
-
-
- 2.1 shouldComponentUpdate函数
- 2.2 React.PureComponent
- 2.3 Component、PureComponent和Immutable
-
-
- 3. 参考链接
1. diff算法
1.1 diff 算法的作用
去掉多余的 DOM 操作,提升web app性能
1.2 reconcilition(调和)
- 定义:将Virtual DOM树转换成actual DOM树的最少操作的过程。diff 算法是调和的具体实现
- 过程: 渲染时调用 render 方法(返回 Virtual Dom 树),比较渲染前后 虚拟dom(Virtual Dom) 的差别,Rendering 时,只更新差别部分(精准update),以减少多余 Dom 操作
1.3 diff算法优化
- 传统 diff 算法 问题: 计算耗时,时间复杂度:O(n^3)
- react diff :时间复杂度 O(n)
- react diff 的三大策略
- 进行同层比较(tree diff)
- 不同类的 React 组件,被当做不同的 Dom 结构而替换(component diff)
- key prop:组件 身份标识,判断是否是同一组件 (element diff)
1.4 tree diff
- 跨层级Dom操作:创建节点,删除节点
- 官方建议:不要进行跨层级操作(使用显示/隐藏,代替删除/新增操作)
1.5 component diff
- 组件变化时,如果 virtual dom 没变,可通过 shouldComponentUpdate 方法控制是否需要 diff 运算
- 组件类不同(结构相似),则判断为 dirty component(脏组件),整个替换
1.6 element diff
- 同层节点 diff 操作:删除、插入、移动
- 移动:尽量减少将类似最后一个元素移动到列表首部的操作(时间复杂度:O(n))
- 图:
f(['A','B','C','D'],['D','A','B','C']) //3
f(['A','B','C','D'],['B','A','D','C']) //2
f(['A','B','C','D'],['B','E','A','C']) //3
//返回移动、插入、删除操作的总次数
function f(old, newS){
var operates = 0
var lastIndex = 0
//新集合遍历,判断是否需要移动、插入
for(let [i,v] of newS.entries()){
let index = old.indexOf(v)
if(index != -1){
if(lastIndex > index){
//移动操作
operates++
}
lastIndex = Math.max(index, lastIndex)
}else{
lastIndex = i
operates++
}
}
//旧集合遍历,计算删除的节点
for(let v of old){
if(!newS.includes(v)){
//删除的相关操作
operates++
}
}
return operates
}
2. Component、PureComponent和Immutable
2.1 shouldComponentUpdate函数
- 监听 props 和 state 的变化(适用于状态少的组件)
class My extends React.Component{
shouldComponentUpdate(nextProps, nextState){
if(this.props.color != nextProps.props.color){
return true
}else if(this.state.count != nextProps.count){
return true
}else{
return false
}
}
}
2.2 React.PureComponent
- React.PureComponent中, shouldComponentUpate对prop和state进行浅对比,没变化则不渲染
- state 和 props 的数据为引用类型时,只会比较数据地址
- 问题:修改对象值,地址不变
- 解决方案:生成新对象,以改变对象内存地址
class My extends React.PureComponent {
state = {
obj: {}
}
change(){
let {obj} = this.state
this.setState({
obj: {...obj}
})
}
}
2.3 Component、PureComponent和Immutable
- React.Component 中,shouldComponentUpate始终返回true,只要有变化,就渲染全部(子组件)
- PureComponent省去了virtual dom的对比过程, 可提升性能
- forceUpate方法: 跳过该组件的 shouldComponentUpdate,调用 render
- 使用 Immutable 可复制数据到新的内存,比直接拷贝 效率高
3. 参考链接
- https://blog.csdn.net/weixin_43606158/article/details/89425451
- https://www.jianshu.com/p/3ba0822018cf
- https://blog.csdn.net/liwusen/article/details/53908266
- https://blog.csdn.net/sinat_36422236/article/details/81117961
- https://www.jianshu.com/p/2fbf85744117