虚拟 DOM 和 DOM diff

159 阅读2分钟

虚拟 DOM 是什么

一个能代表 DOM 树的对象,通常含有标签名、标签上的属性、事件监听和子元素们,以及其他属性

虚拟 DOM 的优点

减少 DOM 操作: 虚拟 DOM 可以将多次操作合并为一次操作,比如你添加 1000 个节点,却是一个接一个操作的(减少频率)虚拟 DOM 借助 DOM diff 可以把多余的操作省掉,比如你添加 1000 个节点,其实只有 10 个是新增的(减少范围)
跨平台: 虚拟 DOM 不仅可以变成 DOM,还可以变成小程序、iOS 应用、安卓应用,因为虚拟 DOM 本质上只是一个 JS 对象

虚拟 DOM 的缺点

需要额外的创建函数,如 createElement 或 h,但可以通过 JSX 来简化成 XML 写法

DOM diff 是什么

就是一个函数,我们称之为 patch,
patches = patch(oldVNode, newVNode)
patches 就是要运行的 DOM 操作

大致逻辑:

  • Tree diff 将新旧两棵树逐层对比,找出哪些节点需要更新
    如果节点是组件就看 Component diff
    如果节点是标签就看 Element diff
  • Component diff 如果节点是组件,就先看组件类型
    类型不同直接替换(删除旧的)
    类型相同则只更新属性
    然后深入组件做 Tree diff(递归)
  • Element diff 如果节点是原生标签,则看标签名
    标签名不同直接替换,相同则只更新属性
    然后进入标签后代做 Tree diff(递归)

DOM diff 的优点

通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验

DOM diff 的问题(key)

如果没有key,DOM diff在节点对比时不会去找原来的节点,而是直接更改节点,这就导致这个节点下的所有子节点都会被改变,出现性能损耗,还会出现bug,合理的应用key,也是一种性能上的优化。