虚拟DOM最核心的部分是patch,它可以将vnode渲染成真实的DOM。
patch也可以叫做patching算法,通过它渲染真实的DOM时,并不是暴力覆盖原有DOM,而是对比新旧两个vnode之间的不同个,根据对比结果找出需要更新的节点进行更新。其实际作用是在现有的DOM上进行修改来实现更新视图的目的。
之所以这么做,是因为DOM操作的执行速度远不如JavaScript的运算速度快。因此,把大量的DOM操作搬运到JavaScript中,使用patching算法来计算出真正需要更新的节点,最大限度的减少DOM操作,从而显著提升性能。本质上其实使用JavaScript的运算成本来替换DOM操作的执行成本,而JavaScript的运算速度比DOM快很多,这样做很划算,所以才会有虚拟DOM。
patch介绍
对比两个vnode之间的差异只是patch的一部分,这是手段不是目的。patch的目的其实是修改DOM节点。也可以理解成渲染视图。上面说过patch不是暴力替换节点,而是在现有的DOM上进行修改来达到渲染视图的目的。对现有的DOM进行修改需要做三件事:
- 创建新增的节点;
- 删除已经废弃的节点;
- 修改需要更新的节点;
我们知道patch的过程其实就是创建节点、删除节点和修改节点的过程,接下来主要讨论在上面情况下创建新节点,插入到上面位置;在上面情况下删除节点,删除哪个节点;在上面情况下修改节点,修改哪个节点。
之所以需要通过算法来比对两个节点的差异,并针对不同的节点进行更新,主要是为了性能考虑。
我们完全可以把整个旧节点从DOM中删除,然后使用最新状态(state)重新生成一份全新的节点插入到DOM中,这种凡是完全是可以实现功能。
由于我们最终的目的是渲染视图,所以可以发现渲染视图的标准是以vnode(使用最新状态创建的vnode)来渲染而不是oldVnode。
新增节点
首先,新增节点的一个很明显的场景就是,当oldVnode不存在而vnode存在时,就需要用vnode去生成真实的DOM并插入到视图中去。
这通常会发生在首次渲染中。因为首次渲染时,DOM中不存在任何的节点,所以oldVnode是不存在的。