首页 > 编程语言 > 详细

Vue虚拟DOM和diff算法

时间:2020-09-13 15:14:18      阅读:56      评论:0      收藏:0      [点我收藏+]

虚拟DOM:

虚拟DOM(Virtual DOM)是对DOM的JS抽象表示,它们是JS对象,能够描述DOM结构和关系。应用 的各种状态变化会作用于虚拟DOM,最终映射到DOM上。

优点:

  • 虚拟DOM轻量、快速:当它们发生变化时通过新旧虚拟DOM比对可以得到最小DOM操作量,配 合异步更新策略减少刷新频率,从而提升性能

  • 跨平台:将虚拟dom更新转换为不同运行时特殊操作实现跨平台

  • 兼容性:还可以加入兼容性代码增强操作的兼容性

必要性:

vue 1.0中有细粒度的数据变化侦测,它是不需要虚拟DOM的,但是细粒度造成了大量开销,这对于大 型项目来说是不可接受的。因此,vue 2.0选择了中等粒度的解决方案,每一个组件一个watcher实例, 这样状态变化时只能通知到组件,再通过引入虚拟DOM去进行比对和渲染。

patch实现:

首先进行树级别比较,可能有三种情况:增删改

  • new VNode不存在就删;

  • old VNode不存在就增;

  • 都存在就执行diff执行更新

diff算法:

  1. diff算法是虚拟DOM技术的产物,vue里面实际叫做patch,它的核心实现来自于snabbdom;通过新旧虚拟DOM作对比(即patch),将变化的地方转换为DOM操作

  2. 在vue 1中是没有patch的,因为界面中每个依赖都有专门的watcher负责更新,这样项目规模变大就会成为性能瓶颈,vue 2中为了降低watcher粒度,每个组件只有一个watcher,但是当需要更新的时候,怎样才能精确找到发生变化的地方?这就需要引入patch才行。

  3. 组件中数据发生变化时,对应的watcher会通知更新并执行其更新函数,它会执行渲染函数获取全新虚拟dom:newVnode,此时就会执行patch比对上次渲染结果oldVnode和新的渲染结果newVnode。

  4. patch过程遵循深度优先、同层比较的策略;两个节点之间比较时,如果它们拥有子节点,会先比较子节点;比较两组子节点时,会假设头尾节点可能相同先做尝试,没有找到相同节点后才按照通用方式遍历查找;查找结束再按情况处理剩下的节点;借助key通常可以非常精确找到相同节点,因此整个patch过程非常高效。

key的作用:

  1. key的作用主要是为了更高效的更新虚拟DOM。

  2. vue在patch过程中判断两个节点是否是相同节点是key是一个必要条件,渲染一组列表时,key往往是唯一标识,所以如果不定义key的话,vue只能认为比较的两个节点是同一个,哪怕它们实际上不是,这导致了频繁更新元素,使得整个patch过程比较低效,影响性能。

  3. 实际使用中在渲染一组列表时key必须设置,而且必须是唯一标识,应该避免使用数组索引作为key,这可能导致一些隐蔽的bug;vue中在使用相同标签元素过渡切换时,也会使用key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

  4. 从源码中可以知道,vue判断两个节点是否相同时主要判断两者的key和元素类型等,因此如果不设置key,它的值就是undefined,则可能永远认为这是两个相同节点,只能去做更新操作,这造成了大量的dom更新操作,明显是不可取的。

Vue虚拟DOM和diff算法

原文:https://www.cnblogs.com/fitnessprogrammer/p/13661014.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!