说在前头:
上文提到了浏览器的重绘和重排,并提到了一些优化的方式。框架的魅力就在于不知不觉的就帮你把事情做掉了,在编写react代码的时候我从没有考虑过添加节点的时候将元素移出文档流等操作。毕业之后就接触了react,但是被问到他的特点是什么还是有点不知所措,今天和大家一起了解一下他的特点,虚拟DOM。
正文:
说之前先看一个例子:
<ul id = 'list'>
<li class="list_li">li-1</li>
<li class="list_li">li-1</li>
</ul>
这段HTML代码在前端中展示出来是一个列表,能不能有一种数据结构,通过数据的方式将它表达出来呢?
{
tag: 'ul',
attrs: {
id: 'list'
},
children: [
{
tag: 'li',
attrs: {
className: 'list_li',
},
children: ['li-1']
},{
tag: 'li',
attrs: {
className: 'list_li',
},
children: ['li-2']
}
]
}
上面的属性基本上可以理解,说一下children,还记得react中this.props.children的用法吗?是的,他代表的就是当前标签里面的内容。
理解了上面的内容,react中的虚拟dom和上面做的事情差不多,他会将当前页面的结构通过这种方式将HTML的DOM节点抽象描述,这个是不需要DOM API的,所以不会有任何的性能问题,这个JavaScript对象就称为***虚拟DOM*** 。当需要重新渲染组件的时候,React自己有一个Diff算法,算到哪些节点发生了变化,然后再映射到实际需要修改的DOM节点上面,这样只会引发一次重排和DOM访问,是很高效的一种实现方式。
再看虚拟DOM
作为框架的特色,他的优势肯定不在于单次操作,而是当项目逻辑复杂,需要经常更新界面的情况下,能够实现的更高效、合理。本质的话,他就是一个JavaScript对象。工作原理如下:
- 生成虚拟DOM树
- 对比新生成的和初始的虚拟DOM树的差异
- 根据对比结果更新视图