Skip to content
扫码联系作者

真实 DOM 和虚拟 DOM

概念

真实DOM
文档对象模型(Document Object Model),它是一种用于表示和操作HTML、XML和SVG文档的编程接口。真实的DOM是一个树形结构,它将文档中的每个元素、属性和文本都表示为一个节点,允许开发者通过JavaScript等脚本语言来操作和修改网页的内容和结构。

虚拟DOM
虚拟DOM(Virtual DOM)是一种用于优化前端渲染性能的概念和技术。它是一个虚拟的、轻量级的JavaScript对象树,用来表示真实DOM的抽象结构。虚拟DOM的核心思想是通过在内存中构建虚拟DOM树,然后通过比较算法将变更映射到实际DOM,从而减少对真实DOM的频繁操作,提高页面渲染的性能。
虚拟DOM的工作原理如下:

  1. 初始化阶段:在页面加载时,将真实 DOM 的初始状态转换为虚拟 DOM 的树结构,这个过程称为虚拟 DOM 的"渲染"。
  2. 数据变更阶段:当页面数据发生变化时,生成一个新的虚拟 DOM 树,与之前的虚拟 DOM 树进行比较。
  3. 比较算法:虚拟 DOM 的比较算法会逐层对比两个虚拟 DOM 树的节点差异,并记录下变更的操作,例如添加、更新或删除。
  4. 更新阶段:通过比较算法得到的变更记录,将只有真正变化的部分应用到实际 DOM 上,即局部更新。

区别

使用方式

真实 DOM

  1. 直接操作:真实 DOM 是 HTML 文档的实际表示,可以通过 JavaScript 直接对其进行操作。开发者可以使用原生的 DOM API(如 document.getElementById、element.appendChild 等)来获取元素并进行增、删,改,查等操作。
  2. 反应式:在某些框架中,使用真实 DOM 进行视图更新时,需要手动监测数据的变化,并手动触发 DOM 更新操作。这通常涉及到手动的状态管理和 DOM 操作,容易导致代码冗余和难以维护。

虚拟 DOM

  1. 中间抽象层:虚拟 DOM 是真实 DOM 的一种抽象表示,它是用 JavaScript 对象模拟了真实 DOM 树的结构。在修改视图时,开发者实际上是在操作虚拟 DOM 树,而不是直接操作真实 DOM。
  2. 声明式:使用虚拟 DOM 时,开发者可以以声明式的方式描述视图状态,而不需要关心具体的 DOM 操作。框架会根据虚拟 DOM 的变化,自动计算出需要更新的最小 DOM 变更,并且将所有 DOM 操作集中处理,最后批量更新真实 DOM。这使得开发者能够将关注点集中在数据和状态上,而不用过多关心 DOM 操作。

优势

真实 DOM

  1. 原生操作:真实 DOM 是浏览器提供的原生接口,直接操作真实 DOM 可以实现几乎任何的视图更新和交互效果。
  2. 支持全面:由于真实 DOM 是浏览器提供的标准 API,因此在各种浏览器上都能得到很好的支持和兼容性。
  3. 熟悉:对于熟悉 DOM 操作的开发者来说,使用真实 DOM 是一种熟悉的开发方式,不需要学习额外的抽象概念。

虚拟 DOM

  1. 高性能:虚拟 DOM 通过在 JavaScript 内部进行操作,减少了对真实 DOM 的直接访问。在数据变更时,虚拟 DOM 会将所有的 DOM 操作进行批量处理和优化,从而减少了浏览器的重绘和重排,提高了性能表现。
  2. 灵活性:虚拟 DOM 是真实 DOM 的抽象层,可以轻松实现跨平台(如 Web、移动端、服务器端)的视图渲染,也方便进行单元测试和快速 UI 迭代。
  3. 跨平台:虚拟 DOM 不仅可以用于浏览器中的前端开发,还可以用于服务器端渲染(SSR),以及一些移动端开发框架(如 React Native)中,实现代码的重用和跨平台开发。

劣势

真实 DOM

  1. 性能损耗:直接操作真实 DOM 会导致频繁的重绘和重排,特别在大规模的数据变更时,性能损耗较高,影响页面的响应速度和用户体验。
  2. 复杂性:真实 DOM 操作相对繁琐,需要手动处理 DOM 的创建、更新和销毁,代码难以维护,尤其在复杂的交互场景下容易出现 bug。
  3. 兼容性:由于不同浏览器对 DOM 的实现存在差异,为了确保在各种浏览器上的一致性,开发者需要编写大量兼容性代码。

虚拟 DOM

  1. 内存消耗:虚拟 DOM 需要在 JavaScript 内部维护一份 DOM 的副本,因此会占用一定的内存空间,尤其在处理大型复杂视图时,可能会导致内存消耗较大。
  2. 学习成本:虚拟 DOM 需要引入额外的抽象概念和编程模式,对于初学者来说,学习成本可能较高。
  3. 构建过程:虚拟 DOM 需要在数据变更时进行比对并计算出最小化的 DOM 更新,这个过程会带来一定的计算开销,尤其在数据量较大时,虚拟 DOM 的构建过程可能会比直接操作真实 DOM 更耗时。

使用场景

真实 DOM

  1. 小规模应用:在小规模的应用中,页面结构相对简单,数据变更较少,直接操作真实 DOM 更为直观和方便。
  2. 交互简单:当应用的交互逻辑较为简单,数据变更频率较低时,真实 DOM 的性能损耗较小,使用真实 DOM 可以简化开发过程。

虚拟 DOM

  1. 大型复杂应用:在大型复杂应用中,页面结构复杂,数据变更频繁,使用虚拟 DOM 可以显著提高性能和响应速度。
  2. 高性能要求:当应用对性能有较高的要求,需要尽量减少重绘和重排时,虚拟 DOM 的优化机制可以有效降低性能损耗。
  3. 组件化开发:在采用组件化开发模式的框架中,虚拟 DOM 可以与组件状态和数据绑定,实现局部更新,提高代码可维护性和可重用性。
  4. 跨平台开发:对于需要跨平台开发的应用,虚拟 DOM 可以在不同平台上提供一致的开发体验,增加开发效率。

影响因素

真实 DOM

  1. 数据变更频率: 数据变更频率高会导致频繁的 DOM 操作,增加页面的重绘和重排次数,降低性能。
  2. DOM 操作复杂度: 复杂的 DOM 操作会引起多次页面重绘和重排,影响渲染性能。
  3. 页面元素数量: 页面元素较多时,DOM 操作会变得更加耗时,影响性能。
  4. 跨浏览器兼容性: 不同浏览器对 DOM 操作的实现有差异,可能导致兼容性问题。
  5. 渲染性能要求: 对于性能要求较高的应用,频繁的 DOM 操作可能无法满足要求。

虚拟 DOM

  1. 数据变更频率: 虚拟 DOM 采用批量更新的方式,当数据变更频率较高时,虚拟 DOM 可以减少实际的 DOM 操作次数,提高性能。
  2. 组件嵌套层级: 组件嵌套层级越深,虚拟 DOM 对局部更新的优势越明显。
  3. 复杂交互: 复杂的交互场景可能导致 DOM 频繁变更,虚拟 DOM 可以优化渲染性能。
  4. 渲染性能要求: 对于性能要求较高的应用,虚拟 DOM 的优化机制可以显著提高性能。
  5. 框架支持: 使用虚拟 DOM 通常需要框架或库的支持,要考虑开发团队对框架的熟悉程度。

开发效率

真实 DOM

  1. 直观性: 直接操作真实 DOM 可以更直观地理解和编写页面结构和交互逻辑,特别是对于简单应用或初学者而言,上手较快。
  2. 生态成熟: 在传统的前端开发中,直接操作真实 DOM 是主流方式,相关生态和工具链比较成熟,如 jQuery 等库。
  3. 少量数据变更: 在应用中,如果只涉及到少量数据变更,直接操作真实 DOM 可能更加简单高效。

虚拟 DOM

  1. 抽象性: 虚拟 DOM 是对真实 DOM 的抽象表示,使用虚拟 DOM 需要掌握其抽象概念和使用方式,可能对于初学者来说有一定的学习曲线。
  2. 框架学习: 使用虚拟 DOM 通常需要借助相应的前端框架(如 React、Vue),需要额外学习框架的 API 和生态,增加了开发学习成本。
  3. 性能优化: 虚拟 DOM 需要借助比较算法来优化渲染性能,对于复杂应用可能需要进行性能优化的处理。
  4. 组件化开发: 虚拟 DOM 通常结合组件化开发方式,将页面划分为多个组件,提高了代码的可维护性和复用性,但也增加了组件拆分和组合的工作量

性能

真实 DOM

  1. 直接操作 DOM: 真实 DOM 直接映射到浏览器的文档对象模型,每次数据变更都会引起实际的 DOM 操作,例如插入、删除、修改节点等。
  2. 频繁重绘与重排: 数据变更导致的频繁 DOM 操作会触发页面的重绘和重排,影响渲染性能。
  3. 性能成本高: 实际的 DOM 操作需要与浏览器进行频繁的交互,执行成本较高,特别是在元素数量较多、操作复杂的情况下。
  4. 局部更新困难: 每次数据变更都要对整个真实 DOM 进行重新渲染,对于复杂的交互场景,可能无法实现局部更新。

虚拟 DOM

  1. DOM 抽象层: 虚拟 DOM 是对真实 DOM 的抽象表示,是一个轻量级的 JavaScript 对象,通过比较虚拟 DOM 的差异来最小化实际 DOM 操作。
  2. 批量更新: 虚拟 DOM 通过批量更新的机制,将多个数据变更合并为一次操作,减少实际 DOM 操作的次数,提高性能。
  3. 最小化重绘与重排: 虚拟 DOM 的比较算法可以最小化重绘和重排次数,只更新发生变化的部分,优化渲染性能。
  4. 局部更新: 虚拟 DOM 可以实现局部更新,只对需要更新的部分进行渲染,提高渲染效率。
  5. 虚拟 DOM 优化: 一些框架(如 React、Vue)对虚拟 DOM 进行了优化,使用了 Diff 算法和 Virtual DOM Reconciliation 策略,进一步提高了性能。

性能对比: 虚拟 DOM 相对于真实 DOM,在性能上有以下优势:

  1. 减少实际 DOM 操作次数: 虚拟 DOM 可以批量更新,将多个数据变更合并为一次操作,减少 DOM 操作次数。
  2. 最小化重绘和重排: 虚拟 DOM 的比较算法可以最小化重绘和重排次数,优化渲染性能。
  3. 局部更新优化: 虚拟 DOM 可以实现局部更新,只对需要更新的部分进行渲染,减少不必要的渲染开销。
  4. 框架优化: 虚拟 DOM 的一些框架(如 React、Vue)进行了优化,进一步提高性能。

总结

真实 DOM 和虚拟 DOM 都有各自的优缺点,在不同场景下都有适用的情况。真实 DOM 直接映射到浏览器的渲染树,性能较高,适用于一些简单的页面。而虚拟 DOM 通过比较差异来减少 DOM 操作,适用于大规模数据变更和复杂交互的页面。因此,在实际开发中,开发者应根据页面的特点和需求,选择合适的 DOM 操作方式,以提高页面性能和开发效率。