虚拟DOM和Diff算法

什么是虚拟DOM?有什么用?

虚拟DOM是对真实DOM的抽象,本质上是JavaScript对象,这个对象就是更加轻量级的对DOM的描述。

首先都知道频繁操作变动真实DOM会引起浏览器的重绘和回流,这会大大降低浏览器的性能,而在 前端性能优化的其中有一个方向就是尽可能操作真实DOM,从而达到提升性能的目的。因为紧紧修改虚拟dom中的内容,不会带来页面的重绘和回流操作。在完成虚拟DOM修改后,进行真实DOM的修改,才会使页面重绘。因此我们需要这层抽象,在path(绘制)过程中尽可能一次性将差异更新到DOM中,这样在一定程度上保证了DOM的性能不会很差。

最后,也是虚拟DOM最初的目的,就是更好的跨平台,比如Node.js就没有DOM,如果想实现SSR(服务端渲染),那么一个方式就是借助虚拟DOM,因为虚拟DOM本身是JavaScript对象。

虚拟DOM的解析过程

  1. 构建虚拟dom树:开发者编写的模板或组件代码被编译器或解析器解析为虚拟dom树。虚拟dom是一个纯JavaScript对象,描述整个页面的结构和内容。
  2. 初次渲染:首次渲染时,将虚拟dom树转换为真实的dom树,并插入页面中。这一过程也称为“挂载”。
  3. 更新虚拟dom:当页面需要更新时,开发者会使用JavaScript代码修改dom树。在这衣蛾过长,不会直接修改真实的DOM。
  4. 比较虚拟DOM:比较修改前后的DOM树,找出需要更新的部分。
  5. 更新真实DOM:根据比较结果,只更新需要更新的真实DOM。这个过程称为重新渲染。

当页面的状态发生改变或需要对页面的DOM树结构进行修改的时候,首先会根据变更的状态重新构建起一颗DOM树,然后将新的DOM树和旧的DOM进行比较,通过diff 算法记录两颗树的差异。最后的差异部分应用到真实的DOM中去,这样视图就会更新。

diff 算法

diff算法是一种对同层DOM节点进行比较的高效算法,传统diff算法通过循环递归对节点进行依次比较,效率低下,算法复杂度达到O(n^3), 而改进后的diff算法避免了对DOM树进行逐层搜索遍历,所以时间复杂度只有O(n)。diff算法在很多场景下都有应用,例如,Vue虚拟DOM渲染成DOM的新旧虚拟DOM节点比较更新时,就用到该算法。

diff算法特点:不会跨层级比较,只会在同层级进行比较,
diff算法的基本原理有以下几点:

  • 对于同层级的节点首先对比新旧节点的头尾、头与头、尾与尾分别进行对比,寻找未移动的节点。
  • 新旧节点头尾对比完后,进行头与尾,尾与头的交叉对比,这一步的目的是寻找可复用的节点。
  • 在交叉对比结束后,因为有可能还有可复用的节点,所以创建一个老节点letToIndex的哈希表map记录key,然后继续遍历信号节点索引通过key查找客服用的旧节点。
  • 节点完成便利后,通过新老索引,移除多余纠结点或者增加新节点。

Vue中key的作用:

  1. 为了性能优化:因为vue底层是虚拟DOM,更新DOM时用diff算法对新旧节点对比,找到客服用的节点,减少操作真实DOM的次数。在更新数据渲染列表时,如果数据的顺序发生了改变,Vue不会移动DOM元素来匹配数据的顺序,而是采用“就地复用”策略,简单地复用此处的每个元素,因此通过每个节点设置一个key值,以便Vue判断节点是否可以服用,从而高效的实现更新渲染虚拟DOM.
  2. 确保正确的组件状态
    在使用带有状态的组件时,如果不适用key,可能会出现状态错乱的问题。使用key可以确保Vue对每个节点都能正确地保存组件状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 。单

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值