Virtual DOM 算法
真正的 DOM 元素是非常庞大的,所以操作它们的时候你要小心翼翼,轻微的触碰可能就会导致页面重排,这可是杀死性能的罪魁祸首。相对于 DOM 对象,原生的 JavaScript 对象处理起来更快,而且更简单。DOM 树上的结构、属性信息我们都可以很容易地用 JavaScript 对象表示出来:
1 | var element = { |
上面对应的HTML写法是:
1 | <ul id='list'> |
既然原来 DOM 树的信息都可以用 JavaScript 对象来表示,反过来,你就可以根据这个 JavaScript 对象表示的树结构来构建一棵真正的DOM树。
用 JavaScript 对象表示 DOM 信息和结构,当状态变更的时候,重新渲染这个 JavaScript 的对象结构。用新渲染的对象树去和旧的树进行对比,记录这两棵树差异。记录下来的不同就是我们需要对页面真正的 DOM 操作,然后把它们应用在真正的 DOM 树上,页面就变更了。这就是所谓的 Virtual DOM 算法,包括几个步骤:
- 用 JavaScript 对象结构表示 DOM 树的结构,然后用这个树构建一个真正的 DOM 树,插到文档当中;
- 当状态变更的时候,重新构造一棵新的对象树,然后用新的树和旧的树进行比较(Diff算法),记录两棵树(新旧虚拟DOM这两个对象)的差异;
- 把步骤2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。
总结
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存;既然 DOM 这么慢,我们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)。