When to Avoid Virtual DOM in React

React’s Virtual DOM is highly efficient for most web applications, but there are specific scenarios where bypassing this abstraction layers is necessary for optimal performance and functionality. This article covers the key situations where you should avoid relying on the Virtual DOM—such as managing focus, measuring element layouts, integrating with imperative third-party libraries, and handling high-frequency animations—and explains how to interact with the real DOM instead.

1. Managing Focus, Text Selection, or Media Playback

React operates on a declarative programming model, but certain browser APIs are inherently imperative. When you need to trigger actions like focusing an input element, selecting text on a page, or controlling HTML5 video and audio playback, the Virtual DOM cannot help.

To handle these actions, you must bypass the Virtual DOM and access the real DOM node directly using React refs (via the useRef hook). Calling methods like .focus(), .select(), or .play() directly on the DOM node is the only way to execute these commands.

2. Measuring Layout and Element Dimensions

The Virtual DOM is a lightweight representation of the UI and does not contain layout information, CSS styles, or physical pixel dimensions. If your application needs to calculate the physical size or position of an element on the screen, you cannot use the Virtual DOM.

Calculating values like getBoundingClientRect(), offsetWidth, offsetHeight, or scroll positions (scrollTop) requires querying the actual browser DOM. You should perform these measurements inside a useLayoutEffect hook using a direct reference to the DOM node, ensuring the measurements are taken after the browser has performed layout but before it paints the screen.

3. Integrating with Imperative Third-Party Libraries

Many powerful libraries, such as D3.js for complex data visualizations, Leaflet for maps, or legacy jQuery plugins, manipulate the DOM directly. If React’s Virtual DOM and an external library try to manage the same DOM nodes simultaneously, they will conflict, leading to rendering bugs and crashed applications.

In these cases, you should render a wrapper element with React, obtain a ref to it, and then hand over complete control of that DOM subtree to the external library. You must prevent React from updating this specific container by returning false from shouldComponentUpdate or by rendering an empty element that never triggers a re-render.

4. High-Frequency Animations and Real-Time Rendering

React’s diffing algorithm introduces a small amount of overhead when comparing the Virtual DOM with the real DOM. While negligible for standard UI updates, this overhead can cause frame drops in high-frequency scenarios like game loops, canvas rendering, or complex 60 FPS animations.

For performance-critical animations or real-time data visualizations, bypass the Virtual DOM entirely. Instead, use a ref to target the element and update its styles directly using inline style mutations combined with the browser’s requestAnimationFrame API. This avoids the React update cycle altogether, resulting in smoother transitions.