10月24, 2016

Vue 2.0 之 Virtual DOM

Vue.js 2.0已经发布了,想必你已经听说了吧。Vue 2.0最大的更新莫过于它引入了虚拟DOM来更新页面。

什么是虚拟DOM呢

虚拟DOM并不是什么新名词, ReactEmber已经用了这种技术来加快页面的渲染和更新。为了更好的理解虚拟DOM,我们先明确几个概念:

更新DOM昂贵且耗时

当我们利用Javascript来操作页面时,浏览器引擎首先要找到指定的DOM节点,然后再进行更新操作,如下代码所示:

document.getElementById("myId").appendChild(myNewNode);

现代Web应用一般比较复杂,包含上百上千个DOM节点,所以更新起来一般比较耗时。一些比较小且频繁更新的操作不可避免的会降低页面响应速度,影响性能。

可以通过Javascript来虚拟地描述DOM

在HTML中,DOM一般是这样描述的:

<ul id="myId">
  <li>Item 1</li>
  <li>Item 2</li>
<ul>

其实,通过Javasript对象也可以来描述DOM:

// 用Javascript描述虚拟DOM的伪代码
Let domNode = {
  tag: "ul"
  attributes: { id: "myId" }
  children: [
    // where the LI"s would go
  ]
};

这就是传说的虚拟DOM了!!!

更新虚拟DOM相对省时且高效

// 一般可以这样来更新虚拟DOM
domNode.children.push("<ul>Item 3</ul>");

如果我们不是通过调用`getElementById'之类的DOM API来更新DOM,而是直接操作虚拟DOM, 我们的代码会简单高效很多。当需要和真正的DOM同步时,我们可以通如下的伪代码来同步:

// 这个函数将调用DOM API来更高效地批量操作DOM,而不是零碎且频繁地操作DOM
sync(originalDomNode, domNode);

虚拟DOM貌似看起来蛮不错,而且Vue.js 2.0已经支持了,但是任何事情都有两面性,我们真的需要虚拟DOM么,或者说,虚拟DOM有啥优缺点呢?

  • 文件大小 为了支持虚拟DOM,必定要增加更多的功能,那文件大小会增大. 不过Vue.js 2.0做的不错,文件大小依然是21.4kb,一些过时无用的内容已经删除了。

  • 内存占用 使用虚拟DOM内存必定会占用更多的内存,所以需要在内存占用和速度性能提升方面找到一个平衡点

  • 虚拟DOM不适合所有的用户场景。如果页面比较复杂,操作频繁,采用虚拟DOM可以较大的提高页面性能。如果是一些比较简单的单一的页面,就得不偿失了。因为虚拟DOM要做一些前置计算,这样就显得不必要了。

所有如果你的页面相对很简单,页面中的DOM也很少,操作也不怎么频繁,使用虚拟DOM反而会是你的页面显得更慢!

虚拟DOM不仅仅能提升性能

在Vue.js 2.0 使用虚拟DOM不仅仅可以提升页面性能,它还提供更多的功能。例如,你可以通过render()方法来通过虚拟DOM来创建正真的DOM:

new Vue({
  el: "#app",
  data: {
   message: "hello world"
  },
  render() {
    var node = this.$createElement;
    return node(
      "div", 
      { attrs: { id: "myId" } }, 
      this.message
    );
  }
});

输出如下所示:

<div id="app">
  <div id="myId">hello world</div>
</div>

也许大家会问,这样有点多余呀,用template不就可以了么?但有时候,template不是万能,如果通过template写DOM太麻烦或者不方便,就可以考虑通过Javascript API的方式来动态生成DOM,这样可以让你全局掌控Vue.js。

直接使用render很方便,但是如果需要创建的DOM很复杂,这样写就有点繁琐了。下篇文章,我们介绍在Vue 2.0中使用类似于React中的JSX语法,这样可以更方便的创建DOM。敬请期待!

备注: 本文原文来自https://medium.com/js-dojo/whats-new-in-vue-js-2-0-virtual-dom-dc4b5b827f40

本文链接:http://www.asyncoder.com//post/vue2-virtual-dom.html

-- EOF --

Comments