秒懂Vue.jsDiff算法与虚拟DOM

一:虚拟DOM

虚拟DOM模仿了实际的 DOM 节点,并包含有关节点的信息,例如标签名、属性、子节点等。

简单举个例子:

js 复制代码
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

Obj = {  // 虚拟dom结构, 根据虚拟dom生成真实dom
  tag: 'ul',
  children: [
    {tag: 'li', children: [{vnode: {text: '1'}}]},
    {tag: 'li', children: [{vnode: {text: '2'}}]},
  ]
}

在运行时,会把代码编译成一个对象,也就是虚拟 DOM,然后生成真实的 DOM,但在实际中,Vue 使用了一种更加复杂的对象结构来存储虚拟节点(VNode),并且包含了更多的元信息,比如节点的类型、属性、事件监听器等等。

二:diff算法

DOM结构发生改变时,会生成一个新的虚拟DOM,此时就需要一个算法来比较新旧DOM的不同来更快速的渲染,也就是diff算法。

比较过程中,会根据虚拟DOM树的结构,一层一层比较,首先比较的是两个虚拟 DOM的根节点是否相同,如果根节点相同才会继续检查子节点,看是否有可复用的DOM,否则不会再继续比较子节点。

那么会有一个疑问了,如果两个虚拟DOM只有根节点不同,子节点完全一样呢?确实,这样的两个新旧虚拟DOM树可复用高,但是如果 diff算法改成了不依据根节点是否相同来确定是否要检查子节点,那么会对逐一对比子节点找可复用部分,加大了引擎压力,有点捡了芝麻丢了西瓜那味了

2.1.判断两个跟节点是不是相同

  1. 判断两个节点上的key是否相同
  2. 判断两个节点的标签名是否相同
  3. 标签上的属性

2.2.diff比较过程

  1. 旧首节点,新首节点,旧尾结点,新尾结点
  2. 不是相同的节点,直接销毁 oldVnode,启用 newVnode
  3. newVnode是不是文字节点 (直接让浏览器修改文字)
  4. 有新的children 没有旧children (记录新增)
  5. 没有新的children 有旧children (记录删除)
  6. 有新的children 有旧childrendiff 核心工作 两两节点比较)

三:diff中的key

3.1.key为什么不能是index?

diff 中判断两个节点是否相同首先判断的就是两个节点的key是否相同, 如果用index作为keyindex不会随着元素位置的变更而移动,从而导致相同可复用的节点被认为不相同,降低了DOM的复用性,浪费性能

3.2.可不可以用随机数做key?

当然不可以,和index的原因是一样的,但比index效率更低下。用随机数的话新旧树的每一个DOM结构都是不同的key,用index,还可能有些DOM结构在新树中index没变,然后得以复用。

四:虚拟DOM的好处

想必友友们在其他文章中已经看过无数遍这个问题的答案了-->因为虚拟DOM性能好。

其实不然,虚拟DOM实际就是把HTML读成JS对象,再生成HTML结构,用虚拟DOM性能并不会有所提高,会开销很多v8的性能。一个新的前端框架svelte就是主打的无虚拟DOM,此外连尤雨溪自己都说在VUE4会把虚拟DOM砍掉。

优点:

  1. 跨平台:支持构建可以在多个平台上运行的应用程序,虚拟 DOM 允许开发者使用一套统一的 API(JavaScript)去描述用户界面,而不需要关心底层的具体实现细节,这在一定程度上促进了跨平台开发。
  2. 分摊了浏览器渲染线程的压力,减少了回流重绘 :当数据发生变化时,diff 算法能够计算出最小化的 DOM 更新操作,这样只需要对实际发生变化的部分进行更新。避免了不必要的 DOM 操作,从而减少了浏览器的回流和重绘,提高页面的响应速度和流畅度。
相关推荐
东风破_5 小时前
danci 项目(三):从 JSON 数据到 AI Coding,真实项目里的数据清洗、Prompt 和工程规范
前端·后端·node.js
东风破_5 小时前
danci 项目(一):从需求到架构,一个单词学习系统为什么会这样设计
前端·后端·node.js
蒲公英eric5 小时前
从客户端到服务端:DVWA DOM 型 XSS 模块完整漏洞分析教程
前端·web安全·ai·xss·dvwa·ai安全
单线程_015 小时前
从案例分析 Vue3 Tokenizer+Parser 源码三
前端·javascript·vue.js
顶点多余6 小时前
那些在算法中适合巩固的知识点---1
java·前端·算法
Setsuna_F_Seiei6 小时前
前端转型 Agent 开发 03 之 Agent Tools - 给 Agent 装上手脚
前端·agent·ai编程
jay神6 小时前
【计算机毕业设计】基于SpringBoot的程序教学辅助系统
java·前端·vue.js·spring boot·后端·毕业设计·课程设计
小磊哥er7 小时前
深入解构Claude Code - 第 8 篇 · 数据放哪、钱怎么算
javascript·ai编程
kyriewen9 小时前
我装了30多个Skill,给AI安排了8个岗位
前端·javascript·ai编程
风骏时光牛马9 小时前
大模型落地实践中的技术选型思路与方案对比
前端