关于虚拟dom和diff算法
虚拟dom是内存的一种轻量化表达
- 虚拟dom是由框架在内存中创建的一颗虚拟树 与真实dom结构相同 它模拟真实的dom结构 但不操作真实dom 实际dom操作耗费时间大 消耗性能大 虚拟dom通过在内存中进行更新 从而通过diff算法比对去更新真实dom 减少了真实dom的操作 从而提升效率 减少资源消耗
- 首先 框架会在内存中创建一个与真实dom结构相同的虚拟dom 然后当数据进行修改时 虚拟dom进行更新 此时虚拟dom和真实dom会通过diff算法去比对出差异 然后真实dom会将发生变化的部分进行更新,这样做是为了避免真实dom做出不必要的更新
diff算法
- 是用来比对真实dom树和虚拟dom树的差异的 从而找出变化 进行最小化的更新 减少对真实dom的操作次数和内容 只更新有变化的部分 重新渲染ui 而不是整体替换
- 首先比较节点 看节点类型是否相同 如一个是 一个是类型不同 则把不同的内容进行整体替换 如类型相同 则比对属性 只有属性有变化的节点才会进行更新 如有子节点 diff算法会递归的对子节点进行对比 如有新增或删除 将会进行替换更新 diff算法递归地处理子节点 所以dom树上再小的变化都会处理到
- 具体流程 diff算法首先会进行新旧虚拟dom对比 采用双端diff算法 即四个指针 分别在新虚拟dom的头尾和旧虚拟dom的头尾 然后分别从头和尾向中间移动 头头比较 尾尾比较 头尾比较 尾头比较 以避免一直从一端进行对比 造成大量没必要的工作 当对比到有变化的位置时 会定义一个变量记录当前位置 以便后续通过打补丁更改真实dom
- 需要注意的是新旧虚拟dom对比节点的时候 key很重要 必须是唯一的 这样vue可以确定哪些节点是没有变化的 从而减少不必要的更新 如果key是下标值 或者没有key 那进行对比时以来的就是节点顺序 而不是唯一值了 这会导致本可以复用的节点被重新渲染 就失去了双端diff算法的意义了