Twlig / issuesBlog

MIT License
3 stars 0 forks source link

为何使用虚拟DOM #40

Open Twlig opened 2 years ago

Twlig commented 2 years ago

命令式DOM带来的问题就是频繁的操作DOM,而主流框架Vue采用声明式操作DOM,关注重点在状态维护上,而操作DOM会由框架代理。通过描述状态和DOM之间的映射关系,将状态渲染成视图。

当某个状态发生变化时,只更新与这个状态相关的DOM节点。在Vue中采用虚拟DOM来实现。

虚拟DOM通过状态生成一个虚拟节点(VNode)树,然后使用虚拟节点树进行渲染。在渲染之前会使用新生成的虚拟节点树和上一次生成的旧的虚拟节点树进行对比,只渲染不同的部分。

为什么使用虚拟DOM而不是watcher?

前面讲到过状态更新可以采用watcher观察,因此其实可以快速定位到需要更新的DOM节点,那么为何还需要采用虚拟DOM呢?其实很容易可以想到watcher观察会带来很高的开销,watcher是用于DOM节点和状态之间通信的中介,对于每一个数据和DOM节点的绑定都需要使用一个watcher(比如一个p标签用到了title属性,就会增加一个watcher用于DOM节点p和状态title属性之间变化侦听),对于一个大型项目来说就会有成百上千个watcher,这个开销是十分庞大的。

  1. title属性发生变化
  2. watcher收到通知
  3. watcher通知p进行DOM更新

因此,为了折中Vue2.0采用组件级别的watcher,也就是一个组件对应一个watcher实例。组件级别的watcher实例监听整个组件用到的状态

  1. 比如A组件中用到了多个状态,那么当状态发生变化
  2. A的watcher就会收到通知
  3. 进而watcher通知组件A进行DOM更新,但是不会具体到A组件的哪个DOM节点。
  4. 因此,此时就需要采用虚拟DOM生成虚拟节点树,进行新旧节点的对比,从而确定如何渲染。

总结: