虚拟DOM
一个可以代表DOM树的对象,通常含有标签名,标签属性,事件监听、子元素和一些其他属性。
在一些情况下,虚拟DOM确实比DOM快,但不代表DOM操作一定比虚拟DOM慢。
虚拟DOM的优点
减少DOM操作的次数
-
虚拟DOM可以将多次操作合并为一次,比如向页面中添加1000个节点,虚拟DOM不需要做一个接一个的拼接操作,而是将这1000个节点放在数组,然后将这些节点一次性放入页面中,这样只需要一次操作就可以将1000个节点放入页面中了。
-
虚拟DOM借助DOM diff可以省掉多余的操作,DOM diff通过对比节点的新旧,只取出新增的节点更新,减少DOM操作的范围。
跨平台
虚拟DOM不仅可以变成DOM,还可以变成诸如小程序、IOS应用、安卓应用、因为虚拟DOM本质上来讲是一个JS对象。
虚拟DOM的缺点
需要额外的创建函数,例如createElement或者h,但可以通过JSX来简化成XML的写法。
DOM diff
DOM diff是什么?
- DOM diff就是一个函数,可以称之为patch。
changed = patch(oldVNode,newVNode)
- changed就是要运行的DOM操作。
changed可能长这样:
[
{type: 'INSERT', vNode: ... },
{type: 'TEXT', vNode: ... },
{type: 'PROPS', propsPatch: [ ... ] }
]
DOM diff的大概逻辑:
Tree diff
- 将新旧两棵树逐层对比,找到哪些节点需要更新。
- 如果节点是组件就看Component diff。
- 如果节点是标签就看 Element diff。
Component diff
- 如果节点是组件,先看组件的类型。
- 类型不同会直接替换(即删除旧节点)。
- 类型相同则只会更新属性。
- 然后深入组件再做Tree diff(递归)。
Element diff
- 如果节点是原生标签,则看标签名。
- 标签名不同直接替换(直接删除旧标签)。
- 标签名相同则只更新属性。
- 然后进入标签后代再做Tree diff(递归)。