什么是virtual dom

用key value形式来描述Dom的对象

  1. {
  2. type: "div",
  3. props: { className: "container" },
  4. children: [
  5. {
  6. type: "div",
  7. props: null,
  8. children: [
  9. {
  10. type: "text",
  11. props: {
  12. textContent: "Hello React"
  13. }
  14. }
  15. ]
  16. },
  17. {
  18. type: "p",
  19. props: null,
  20. children: [
  21. {
  22. type: "text",
  23. props: {
  24. textContent: "React is great"
  25. }
  26. }
  27. ]
  28. }
  29. ]
  30. }

为什么虚拟dom能够提高效率

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

javascript对象与DOM树

真正的DOM元素是非常庞大,属性之多,操作它们可能会导致页面重排。如下把简单的div的属性都打印出来
相对于DOM对象,原生的javascript对象处理起来更快,而且简单。DOM树上的结构、属性信息我们都可以很容易的用javascript对象表示出来。

  1. var element = {
  2. tagName: ul,
  3. props: {
  4. id: 'list',
  5. },
  6. children: [
  7. {tagName: 'li', props: {class: 'item', children: ['item 1']}},
  8. {tagName: 'li', props: {class: 'item', children: ['item 2']}},
  9. {tagName: 'li', props: {class: 'item', children: ['item 3']}},
  10. ]
  11. }

上面对应的HTML写法是:

  1. <ul id="list">
  2. <li class="item">item 1</li>
  3. <li class="item">item 2</li>
  4. <li class="item">item 3</li>
  5. </ul>

既然真正的DOM树的信息都可以用javascript对象来表示,反过来,你就可以根据这个用javascript对象表示的树结构来构建一颗真正的DOM树。

Virtual DOM算法步骤

Virtual DOM算法的步骤:

  • 1、用js对象结构表示DOM树结构;然后用这个树构建一个真正的DOM树,插入到文档中
  • 2、当状态变更的时候,重新构造一颗新的js对象树。然后用新的树和旧的树进行比较,记录两颗树差异
  • 3、把2步骤所记录的差异应用到步骤1构建的真正的DOM树上,视图就更新了

Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存:既然DOM这么慢,我们就在它们JS和DOM之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)。