虚拟DOM是React的一种用于提高渲染效率机制,今天我们来看看虚拟DOM的主要原理。
为什么要使用虚拟DOM
传统JQuery的问题
- 如果直接操作真实的DOM,每次修改都会造成DOM的重绘和重排。高频操作效率很低。
- JS直接操作DOM,效率不高。
- model和view耦合。
React的解决方案
- 响应式,数据变化UI自动变化
- 使用虚拟DOM,合并频繁操作
React的虚拟DOM
React框架核心:React virtual DOM -> 浏览器真实DOM
使用虚拟DOM树的优点如下:
- 比较两棵DOM树之后,只动变更的节点。所以Component只需要处理state即可。
- 虚拟DOM树本质是js对象,生成和比较的效率比真实的DOM树高太多。
- 比较的也是虚拟的DOM树,然后将变动的部分映射到真实的DOM树上。
React的setState方法:
- setState不是马上执行,而是被放入一个队列中,可添加callback来监听state的变化
- 在update中调用setState可能会引起循环问题
PureComponent:
- 目的: 如果state和prop没有发生变化,则不会调用render,减少渲染的次数
- 原理:在shouldComponentUpdate中进行了一次state和prop的浅比较
- 浅比较:只比较每一个key两者是否都有,且是否是一个引用。所以只比较了一层而已。
React数据视图更新原理
- state数据
- JSX模板(render中定义)
- 数据 + 模板生成虚拟DOM(虚拟DOM是一个JS对象,用来描述真实DOM)
['div', {id:'abc'}, ['span',{},'hello world']]
- 用虚拟DOM的结构生成真实的DOM,来显示
<div id='abc><span>hello world</span></div>
- state发生变化
- 数据 + 模板生成新的虚拟DOM
['div', {id:'abc'}, ['span',{},'bye bye']]
- 比较原始虚拟DOM与新的虚拟DOM的区别,找到区别是span中的内容,diff算法
- 直接操作DOM,改变span中的内容
优点:
- 性能提升了,减少了真实DOM的创建和对比,取而代之的是虚拟DOM
- 使得跨端应用得以实现,React Native,将虚拟DOM对应到native组件中
diff算法的核心
- 同层比对。确实会造成DOM渲染的浪费,但是会提高比对的效率。
具体怎么提高?提高了多少?时间复杂度多少? - React引入key值,实现快速比对:
不要用index作为key值。如果列表变化,index会变化,就无法达到key值快速比对的效果了。
提高列表渲染效果,需要使用一个稳定的key值。
响应式设计思想和事件绑定
- 不要直接操控DOM,操控数据
- 数据变化,页面自动变化
常用优化方法
React最耗性能的地方:update和diff,优化的重点就是减少这两个方法的调用
- setState优化主要在于非批更新阶段中(timeout/Promise回调),减少setState的触发次数。
- 为了减少渲染,state和props尽量放需要渲染的数据,不需要渲染的数据使用Context或公共模块(单例服务)变量来实现。
- 在shouldComponentUpdate中比较props的变化,如果props变化不需要重新渲染,可以在此处拦截
网友评论