VDOM的必要性?
说真的,看了很多这个问题的答案,都不太明白这个Vue为什么要用VDOM,说它性能高,是跟什么方法做对比?因为是在Vue2.x才接触的Vue,所以不是很清楚之前是怎么做的。然后自己在学习实践的过程中,有一些自己的思考,想在这里请教各位前端的前辈。
创建真实DOM的代价高
有个说法是这样说的:真实的DOM节点node实现的属性很多,而vnode仅仅实现一些必要的属性,相比起来,创建一个vnode的成本比较低。
So~!这个说法是指什么使用场景呢?如果说创建node成本高,但是就算使用vnode,在diff之后,还不是一样要创建node然后插入到DOM tree当中?而使用vnode的区别在于diff后仅仅生成改变的node去插入到DOM中,那是不是说,如果我只修改受到数据变动的node,那岂不是效果更好?在某些场景下,比如仅仅是修改文本节点的textcontent,那连node都不要重新创建了,更不需要去替换,只需要修改对应node一些相关属性而已,这样岂不是性能更佳?
触发多次浏览器重绘及回流
还有一个说法,是使用vnode,相当于加了一个缓冲,让一次数据变动所带来的所有node变化,先在vnode中进行修改,然后diff之后对所有产生差异的节点集中一次对DOM tree进行修改,以减少浏览器的重绘及回流。
这个我就更不是很能理解了。vnode在diff之后,如果发现有多个node节点产生变化,不是一样也是一个一个的去修改变动的node节点,这个时候不是也是改一次,浏览器就重绘一次??还是说浏览器有什么API是可以批量修改node节点就像事务处理那样,然后再统一的一次commit进行处理,统一的重绘?有这样的API么?
So
如果说,将数据,跟对应的节点直接做绑定,然后当数据改变的时候,直接去修改绑定的节点(可能是多个),改变他们的属性,可以预见的是,在对CSS属性修改、文本节点内容的修改、以及if-else这类的逻辑来说,这类业务逻辑有一个统一的特性就是他们的DOM结构其实是不会改变的,顶多就是Node的属性发生变化,那这类操作是不是不用VDOM那套而是直接将数据跟Node绑定,数据变化直接触发对应的修改方法,产生的性能消耗,尤其是所谓浏览器的重绘,应该跟使用VDOM是一样的,而且还不需要创建新的node,这样不是更好么?
引入 Virtual DOM 在性能方面的考量仅仅是一方面。
正如你说的,性能受场景的影响是非常大的,不同的场景可能造成不同实现方案之间成倍的性能差距,所以依赖细粒度绑定及 Virtual DOM 哪个的性能更好还真不是一个容易下定论的问题。
Vue 之所以引入了 Virtual DOM,更重要的原因是为了解耦 HTML 依赖,这带来两个非常重要的好处是:
综上,Virtual DOM 在性能上的收益并不是最主要的,更重要的是它使得 Vue 具备了现代框架应有的高级特性。