虚拟DOM和性能优化-《React进阶之路》第五章读书笔记

虚拟DOM和性能优化

1.虚拟Dom

虚拟DOM是和真实DOM相对应的,是对结构化文本的抽象表达,即对HTML文本的抽象表达,
虚拟DOM是建立在真实DOM上,对真实DOM的抽象,以解决DOM操作效率低下的问题
使用普通的js对象来描述元素

2.Diff算法

React的调和过程:每次组件的状态和属性更新,组件的render方法都会返回一个新的虚拟DOM对象,用来描述新的UI结构,React会通过比较两次虚拟DOM结构的变化找出差异部分,更新到真实DOM上,从而减少最终要在真实DOM上的操作,提高执行过程,这一过程就是React的调和过程

调和过程的关键是比较两个属性结构的Diff算法
注意:Diff算法比较的是新旧虚拟DOM,只是更新结果更新到真实DOM上

正常情况下,树形结构差异的算法的时间复杂度是O(N^3),React通过总结DOM操作的实际场景,提出了两个在绝大多数情况下都成立的假设,基于这两个假设,实现了在O(N)时间复杂内完成的两颗虚拟DOM树的比较
1)如果两个元素的类型不同,那么生成两颗不同的树
2)为列表的元素设置key属性,用key标识对应元素的在多次render过程中是否发生变化
React比较两颗树是从树的根节点开始比较,根节点的类型不同,执行的操作也不同

2.1根节点比较
2.1.1根节点是不同类型

组件A变为组件B,标签C变为标签D,组件A变为标签C
如果根节点类型发生变化,React会认为新的树和旧的树完全不同,不会继续比较其他属性和子节点,而是销毁就DOM,创建新DOM(包括虚拟DOM和真实DOM)
DOM节点类型分为DOM元素类型React组件类型
在旧的虚拟DOM被拆除的过程中,旧的元素类型的节点会被销毁,旧的组件实例的componentWillUnmount会被调用
在重建的过程中,新的DOM元素会被插入DOM树中,新的组件实例的componentWillMount和componentDidMount方法会被调用,重建的虚拟DOM树会被整体更新到真实DOM树中。这种操作需要大量DOM操作,更新效率最低

2.1.2根节点是相同的DOM元素类型

会保留根节点,比较根节点的属性,然后只更新那些变化了的属性(包括子节点)

2.1.3根节点是相同的组件类型

组件实例不会被销毁,而是执行更新操作,同步变化的属性到虚拟DOM上,这一过程组件实例的componentWillReceiveProps()componentWillUpdate()会被调用。

对于组件节点,React是无法直接知道如何更新真实DOM树,需要在组件更新并且render方法执行完成后,根据render返回的虚拟DOM树结构决定如何更新真实DOM

比较完根节点之后,会以同样的原则继续递归比较子节点,每个子节点相对于其层级以下的节点来说又是一个根节点。如此递归比较,直到比较完两棵树上所有节点,计算得到最终的差异,更新到DOM树中

2.2父节点下多个子节点

默认情况下,React会按照顺序逐一比较两棵树上对应的节点
但是,如果子节点顺序被打乱,更新效率将会下降,因此React提供了key属性作为标记。
当一组子节点定义了key,React会根据key来匹配子节点,在每次渲染之后,只要子节点的key值没有变化,就认为是同一节点

尽量不要使用列表的索引值作为key,因为当列表中的元素顺序发生改变的话,可能会导致大量的key失效,进而引起大量的修改操作

3.性能优化

3.1使用生产环境版本的库

3.2避免不必要的组件渲染

使用shouldComponentUpdate
父组件的每次render都会触发子组件componentWillReceiveProps的调用,进而调用子组件的render方法,但是子组件的props可能并没有发生变化,改变的只是父组件的props和state,所以子组件的render是没有必要的,不仅多执行了一次render和多比较了一次虚拟DOM。
使用shouldComponentUpdate可以避免调用子组件的更新过程
使用浅比较(只比较对象的第一层属性),可以使用React的PureComponent来代替手写shouldComponentUpdate逻辑

class C extends React.PureComponent{}

3.3使用key

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Router是一个用于构建单页面应用程序的库。它提供了一种在React应用程序中管理路由的方式。React Router DOMReact Router的一个扩展,用于在Web应用程序中进行路由。 React Router DOM 5和React Router DOM 6之间有几个重要的区别: 1. 安装方式:React Router DOM 5使用npm包管理器进行安装,命令为`npm install react-router-dom`。而React Router DOM 6使用yarn进行安装,命令为`yarn add react-router-dom@next`。 2. 路由组件:在React Router DOM 5中,使用`<Route>`组件来定义路由。而在React Router DOM 6中,使用`<Route>`组件的替代方案`<Routes>`来定义路由。 3. 路由匹配方式:React Router DOM 5使用基于路径的匹配方式来确定哪个路由应该被渲染。而React Router DOM 6引入了新的匹配方式,称为元素匹配(element matching),它可以根据组件的类型来匹配路由。 4. 嵌套路由:在React Router DOM 5中,嵌套路由需要使用嵌套的`<Route>`组件来定义。而在React Router DOM 6中,可以使用嵌套的`<Routes>`组件来定义嵌套路由。 5. 动态路由:在React Router DOM 5中,可以通过在路径中使用参数来定义动态路由。而在React Router DOM 6中,可以使用`<Route>`组件的新属性`element`来定义动态路由。 6. 错误处理:React Router DOM 5使用`<Switch>`组件来处理路由匹配错误。而React Router DOM 6使用`<Routes>`组件的新属性`fallback`来处理路由匹配错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值