React提高04 对虚拟DOM和加载过程的理解
已同步到个人博客,欢迎访问。
React虚拟DOM的理解
虚拟DOM是用JS的对象结构模拟出html中DOM的结构,批量的增删改查,由于直接操作的是JS对象,所以速度要比操作真实DOM要快,最后更新到真正的额DOM中
虚拟DOM构建的对象,除了dom相关属性,还包括了React自身需要的属性,比如ref,key等,大概如下结构:
{ type: 'div',
props: {
className: 'xxx',
children: [{
type: 'span',
props: {
children: ['CLICK ME']
},
ref: key:
}, {
type: Form,
props: {
children: []
},
ref: key:
}] | Element
}
ref: 'xxx',
key: 'xxx'
}
react何时将虚拟DOM渲染为真实DOM
render这个步骤就是react组件挂载的步骤
react组件挂载:将组件渲染,并构建DOM元素然后插入页面的过程
render的步骤是创建虚拟DOM,挂载组件,
在render之后,将这个虚拟 dom 树真正渲染成一个 dom 树,插入了页面,可以认为是在componentDidMount这个步骤完成的,该方法被调用时,已经渲染出真实的 DOM
在组件存在期,componentDidUpdate与componentDidMount类似,在组件被重新渲染后,此方法被调用,真实DOM已经渲染完成
react不能setState的步骤
shouldComponentUpdate和componentWillUpdate就会造成循环调用,使得浏览器内存占满后崩溃
virtual DOM 的理解
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
- 把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存:既然 DOM 这么慢,我们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)。
为什么虚拟DOM比原生DOM性能更高
React 的基本思维模式是每次有变动就整个重新渲染整个应用,相当于设置 innerHTML,只不过它设置的是内存里面 Virtual-DOM,而不是真实的 DOM。
React.js 厉害的地方并不是说它比 DOM 快(这句话本来就是错的),而是说不管你数据怎么变化,我都可以以最小的代价来更新DOM。方法就是在内存里面用新的数据刷新一个虚拟的DOM数,然以后新旧DOM树进行比较,找出差异,再将差异更新到真正的DOM 树上。
原生DOM性能低,因为DOM 的规范迫使浏览器在实现的时候为每一个 DOM 元素添加了非常多的属性,然而这其中很多我们都用不到
而React对虚拟DOM的属性进行了精简,非常轻量化,并且使用了diff的算法,比较前后差异,最后只把变化的部分一次性应用到真实的DOM树
React 的变动检查由于是 DOM 结构层面的,即使是全新的数据,只要最后渲染结果没变,那么就不需要做无用功。
更正确的说法应该是:虚拟DOM不一定比原生DOM性能高,但是让开发者更省心的更新数据
首先, 虚拟dom并没有比直接原生操作更快, 所谓"快"是有条件的
比如点赞, 数字+1, 直接操作dom会更快.
如果你能自己捋请规则, 每回手动操作dom的时候, 都只改动应该改变的, 那dom操作永远比虚拟dom快.
但如果你的改动勾连的地方很多, 而且要保持状态, 那虚拟dom的自动diff无疑会让你省更多心.
比如一个列表, 列表项有点赞等状态, 回复数量等信息, 有动态新增, 有动态加载, 这时候你要直接操作dom会很繁琐.
虚拟dom的核心在于diff, 它自动帮你计算那些应该调整, 然后只修改该修改的区域, 省下的不是运行速度这种小速度, 而是开发速度/维护速度/逻辑简练程度等"总体速度"
diff算法
比较两棵DOM树的差异是 Virtual DOM 算法最核心的部分这也是所谓的 Virtual DOM 的 diff 算法。两个树的完全的 diff 算法是一个时间复杂度为 O(n^3) 的问题。但是在前端当中,你很少会跨越层级地移动DOM元素。所以 Virtual DOM 只会对同一个层级的元素进行对比:
上面的div只会和同一层级的div对比,第二层级的只会跟第二层级对比。这样算法复杂度就可以达到 O(n)。
参考
- https://www.zhihu.com/question/31809713?sort=created
- https://segmentfault.com/q/1010000009401008?_ea=1922362/*&^%$
- https://www.zhihu.com/question/29504639
以上是 React提高04 对虚拟DOM和加载过程的理解 的全部内容, 来源链接: utcz.com/z/381304.html