← 返回目录

第 11 卷

第 11 / 12 卷日期:

3步:

  • 解析(Parse):通过正则表达式扫描模板字符串,将其解析为抽象语法树(AST),描述模板

的节点结构、属性、子节点等信息;

  • 优化(Optimize):遍历AST,标记静态节点(内容不变的节点)和静态根节点,为后续diff优

化做准备;

  • 生成(Generate):遍历优化后的AST,将其转换为JS代码(即render函数),该函数内部通

过 createVNode 创建VNode。

  1. 第二阶段:VNode创建(执行渲染函数):

组件初始化或数据变化时,会执行编译生成的render函数,通过 createVNode(Vue3)或 h 函数(Vue2)创建VNode对象。创建过程中,会根据节点类型(元素节点、组件节点、文本节点等)

封装对应的VNode属性,如元素节点的 type 为标签名、 props 为标签属性,组件节点的 type 为组件对象等。对于嵌套节点,会递归创建子VNode,形成完整的VNode树。

  1. 第三阶段:VNode渲染/更新(真实DOM挂载/更新):
  • 初次渲染(挂载):通过 patch 函数(Vue3核心更新函数)将VNode树渲染为真实DOM。

patch 函数会根据VNode的 type 创建对应的真实DOM节点,设置节点属性( props),再递归渲染子VNode并挂载到父节点,最终将根VNode对应的真实DOM挂载到页面容器(如

#app)。

  • 数据更新(重新渲染):数据变化触发响应式系统,重新执行render函数生成新的VNode树。

patch 函数对比新旧VNode树的差异(diff算法),计算出需要更新的“补丁”(如属性修改、子节点新增/删除),仅将差异部分应用到真实DOM,完成页面更新。

  1. DIFF算法的原理是什么?它是如何提高性能的?

一、DIFF算法的核心原理

DIFF算法(差异算法)是虚拟DOM的核心,其核心目标是高效对比新旧两棵VNode树的差异,计算出最小更新范围。Vue的DIFF算法遵循“同层级对比”“先序遍历”“key复用”三大核心原则,具体原

理如下:

  1. 同层级对比,拒绝跨层级遍历:

DIFF算法仅对比新旧VNode树中同一层级的节点,不进行跨层级对比。若某一层级节点类型不匹配(如旧节点是'div',新节点是'p'),则直接销毁该层级及以下的旧VNode,创建新的VNode树并挂

载,避免了复杂的跨层级差异计算,降低算法复杂度(时间复杂度从O(n³)降至O(n))。

  • 属性对比:若节点类型相同,对比节点的 props 属性,仅更新变化的属性(如新增/删除

class、修改style等);

  • 子节点对比:若节点有子节点,进入子节点对比逻辑(核心难点),通过“key匹配”策略复用

节点,减少销毁/创建操作。

  1. key复用,优化列表对比:

对于列表类子节点(如 v-for 渲染的节点),通过节点的 key 属性判断是否可复用。key是节点的唯一标识,新旧节点key匹配则说明节点可复用,仅需更新属性和子节点;key不匹配则销毁旧节

点、创建新节点。Vue3进一步优化列表对比,引入“最长递增子序列”算法,减少节点移动操作。

二、DIFF算法提高性能的核心逻辑

  1. 减少真实DOM操作次数:

DIFF算法的核心价值是“计算最小更新范围”,避免全量重新渲染。通过对比新旧VNode树,仅将差异部分(补丁)应用到真实DOM,而非直接替换整个DOM树,大幅减少了真实DOM的创建、删

除、修改操作,降低了重排/重绘开销。

  1. 通过优化策略降低对比开销:
  • 同层级对比简化算法逻辑,将时间复杂度从O(n³)(全量对比)降至O(n)(线性对比),提升对

比效率;

  • key复用策略避免了“就地复用”(无key时)导致的节点状态混乱,同时减少了不必要的节点

销毁/创建;

  • Vue3新增的PatchFlags优化:编译阶段标记动态节点(如动态文本、动态class),DIFF阶段仅

对比标记的动态部分,忽略静态节点,进一步减少对比开销。

  1. 批量更新,减少重排/重绘:

DIFF算法计算出的差异会被收集到“更新队列”中,批量应用到真实DOM。批量更新可避免频繁的单个DOM操作触发多次重排/重绘,合并为一次重排/重绘,显著提升性能。

  1. 虚拟DOM和真实DOM在性能上的对比如何?

虚拟DOM和真实DOM的性能对比需分场景讨论,核心结论是:单次操作真实DOM更快;批量更新/复杂场景下,虚拟DOM通过减少真实DOM操作次数,性能更优。具体对比从3个维度展开:

一、单次操作性能:真实DOM > 虚拟DOM

虚拟DOM是对真实DOM的抽象,其操作本质是JS对象的操作(创建、修改属性等),而真实DOM操作是浏览器引擎的原生操作。但单次操作场景下(如创建一个简单节点并挂载),虚拟DOM需额外执

行“创建VNode→diff对比→应用补丁”三步,而真实DOM可直接调用

VNode+diff+挂载,多一步diff开销)

二、批量更新/复杂场景性能:虚拟DOM > 真实DOM

复杂场景(如列表重排、多属性同时修改、条件渲染组合)或批量更新场景下,真实DOM的性能劣势明显,虚拟DOM的优势凸显:

  1. 真实DOM的性能瓶颈:每一次真实DOM操作都会触发浏览器重排/重绘,批量操作时会产生大量冗

余的重排/重绘。例如,修改10个列表项的文本,直接操作真实DOM会触发10次重排;若同时修改属性、子节点,重排次数会更多,性能开销极大。

  1. 虚拟DOM的性能优势:通过diff算法计算出所有需要更新的差异,将批量操作合并为一次真实DOM

更新。例如,修改10个列表项文本,虚拟DOM仅需一次diff对比,然后批量更新10个节点的文本内容,仅触发1次重排,大幅降低开销。

三、长期运行/大型应用性能:虚拟DOM更稳定

大型应用中,页面状态频繁变化(如表单输入、列表筛选、数据分页),真实DOM操作若缺乏统一管理,易出现“重复更新”“无效更新”(如多次修改同一属性)。虚拟DOM通过响应式系统精准触发

更新,配合diff算法过滤无效更新,仅保留必要的真实DOM操作,长期运行性能更稳定。此外,Vue3 的编译优化(静态提升、PatchFlags)进一步优化了虚拟DOM的对比效率,让大型应用的性能优势更

明显。

总结对比表

对比场景真实DOM性能虚拟DOM性能优势方
单次简单操作(创建/修改单高(无额外对比开销)中(需创建VNode+diff)真实DOM

个节点)

批量更新(如修改10个节点低(多次重排/重绘)高(批量差异更新,一次重虚拟DOM
属性)排)
大型应用/频繁状态变化低(易出现无效更新、重复更高(精准更新+编译优化)虚拟DOM

新)

  1. Vue中key的作用是什么?为什么需要绑定key?

一、key的核心作用

全站分卷索引 · 12 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷