Why is Vue.js using a VDOM?

2019-03-27 16:59发布

According to Vue.js' documentation, it is using a VDOM under the hood to render the UI. From my understanding, the VDOM was mainly invented in order to avoid "tracked dependencies". With a VDOM, it is possible to reconcile bigger parts of the application without knowing what exactly has changed. As a result, one can use plain objects and arrays to describe the view and just needs to inform the framework about a change (like setState in React). Then, both VDOM trees are compared and the minimal set of required changes is applied to the real DOM.

Vue.js, on the other hand, uses tracked dependencies. It knows exactly what has changed, so it would be possible to use DOM bindings. Furthermore, since most Vue.js users are already using the templating language, it doesn't really benefit from the greater flexibility provided by a VDOM. So why did Evan decide to use a VDOM?

1条回答
甜甜的少女心
2楼-- · 2019-03-27 17:31

There are several aspects to this design decision.

  1. Maintainability and flexibility. Direct DOM bindings (as in Vue 1.x) are indeed efficient and straightforward for single bindings, but not so much when lists are involved. It gets even more complicated when composition is involved (e.g. the slots mechanism). For each kind of such features (that involves composition of fragments), special-purposed stateful code needs to be written and they may affect each other, making the system harder to maintain. Using a VDOM cleanly separates the eventual DOM manipulations from the feature layer - the feature code now works by declaratively composing VNodes, making it much easier to maintain and add new features.

    In addition, this flexibility of VDOM can also be exposed to users by allowing them to bypass the template and directly author render functions.

  2. VDOM diffing is not free - in fact it could be quite expensive when you setState() at the root of a large component tree. This is why in React you need to use PureComponent or implement shouldComponentUpdate to bypass part of the component tree. With a dep tracking system, we can automatically and more accurately detect the components that need to update, so even VDOM can benefit from having a dep tracking system.

  3. Dependency tracking also has its costs - for each binding it needs to allocate memory for tracked dependencies. Super fine-grained bindings means there will be thousands of reactive watchers in an app, leading to extra memory usage. How granular the tracking system should be is dependent on what type of apps we are building. Based on observation of typical app structures, Vue 2 uses a somewhat "medium-grained" strategy by tracking dependencies for each component, thus making each component a reactive update boundary.

So - combining the two we kind of get the benefits from both sides :)

查看更多
登录 后发表回答