React 虚拟 DOM | 青训营

38 阅读4分钟

React 的虚拟 DOM(Virtual DOM)是其核心机制之一,它通过使用虚拟 DOM 对比算法来提高性能和效率。

一个虚拟 DOM

一个虚拟 DOM 对象会经由初始化、渲染、对比、更新和应用更新的过程:

初始化:当创建 React 组件时,React 会为每个组件创建一个对应的虚拟 DOM 树。虚拟 DOM 树是一个轻量级的 JavaScript 对象树,它以组件的层次结构来表示用户界面的结构。

渲染:当应用程序的状态发生变化时,React 会重新渲染组件。在重新渲染之前,React 会先生成一个新的虚拟 DOM 树,表示组件在新状态下的界面结构。

对比:接下来,React 会将新的虚拟 DOM 树与之前的虚拟 DOM 树进行对比。React 使用一种高效的算法来找出两个树之间的差异,并记录下这些差异。

更新:基于对比的结果,React 知道了哪些部分需要更新。然后,React 会将只需要更新的部分应用到实际的 DOM 上,而不是重新渲染整个界面。

应用更新:React 将更新应用到实际的 DOM 上,使得用户界面与最新的状态保持一致。

通过使用虚拟 DOM,React 实现了高效的界面更新。相比直接操作实际的 DOM,虚拟 DOM 具有以下优势:

  • 减少实际 DOM 操作:React 通过对比虚拟 DOM 树的差异,最小化实际 DOM 操作的数量。这样可以提高性能,避免了频繁的 DOM 操作带来的性能开销。
  • 批量更新:React 将多个更新操作合并为一个批量更新操作,减少了实际 DOM 操作的次数,提高了性能。
  • 跨平台支持:虚拟 DOM 不依赖于特定的平台或浏览器,可以在不同的环境中使用,例如浏览器、移动端等。

总之,React 的虚拟 DOM 机制使得界面更新更加高效,同时提供了灵活性和跨平台支持,为开发者提供了良好的开发体验。

批量更新

React 实现批量更新操作的机制是通过使用 "批处理"(batching)的方式来收集多个状态更新,然后一次性地进行更新。

具体来说,当组件的状态发生改变时,React 并不会立即进行更新,而是将状态改变的操作放入一个待处理的队列中,等待后续处理。

在 React 内部,有一个被称为 "事务"(transaction)的概念,用于管理状态更新的过程。React 通过 "事务" 来实现批量更新操作。事务会通过一些机制来延迟实际的更新操作,直到合适的时机。

以下是 React 实现批量更新的一般流程:

  1. 发起状态更新:当组件的状态发生改变时,开发者调用 React 提供的 setState 方法来更新状态。
  2. 将状态更新放入队列:React 将状态更新的操作放入一个待处理的队列中,而不是立即执行更新操作。
  3. 延迟更新操作:React 使用一种机制延迟实际的更新操作。通常,React 会使用 requestIdleCallbackrequestAnimationFrame 来在浏览器空闲时执行更新操作。这样可以避免阻塞主线程,提高性能和用户体验。
  4. 批量处理更新:当浏览器空闲时,React 开始处理待处理队列中的状态更新操作。React 会对队列中的更新操作进行合并和优化,以减少实际 DOM 操作的次数。
  5. 应用更新:React 将合并后的更新操作应用到实际的 DOM 上,使得界面与最新的状态保持一致。

通过批量更新操作,React 可以将多个状态更新合并为一个更新批次,从而减少了实际 DOM 操作的次数,提高了性能。

需要注意的是,React 并不保证所有情况下都会触发批量更新。在某些情况下,如在事件处理函数或异步回调中调用 setState,React 可能会立即执行更新操作而不是进行批量更新。这是为了确保更新的及时性和准确性。