← Back to blog

React 19.2+ and the Compiler Era: What It Means for Trading UIs

React Compiler 1.0 brings automatic memoisation to production. Here's what changes for trading applications - what you can remove, what you should keep, and the new APIs that matter.

By Oliver Benns


React 19.2 and the simultaneous release of React Compiler 1.0 represent the biggest shift in how we think about React performance since hooks replaced class components. For trading applications - where render performance is directly tied to product quality - this is worth paying close attention to.

What the React Compiler actually does

React Compiler is a build-time tool that analyses your components and hooks, then automatically inserts memoisation where it determines re-renders can be avoided. It runs as a Babel plugin (or via Vite/Rsbuild integration) and transforms your source code before it reaches the browser.

Previously, avoiding unnecessary re-renders required manual intervention: wrapping components in React.memo, stabilising values with useMemo, and preserving function references with useCallback. The compiler does this automatically, and often more granularly than a developer would - it can memoise individual values conditionally, something that is not possible with manual hooks.

Meta reports up to 12% faster initial loads and more than 2.5x faster interactions in production applications like the Quest Store. Those numbers are significant, but the real impact for trading applications is more nuanced.

What you can remove

With the compiler enabled, much of the manual memoisation in a trading codebase becomes redundant. Specifically:

React.memo wrappers on leaf components - The compiler automatically determines when a component's props have not changed and skips the re-render. You no longer need to wrap every order book row or position grid cell in React.memo.

useMemo for derived values - Calculations like formatting prices, computing P&L, or aggregating position totals no longer need explicit memoisation. The compiler tracks dependencies and caches results automatically.

useCallback for stable function references - Event handlers passed as props no longer need to be wrapped in useCallback to prevent child re-renders. The compiler stabilises references where it determines they are needed.

// Before: manual memoisation everywhere const PositionRow = React.memo(({ position }: Props) => { const pnl = useMemo( () => calculatePnl(position), [position.quantity, position.avgPrice, position.currentPrice] ); const handleClose = useCallback( () => closePosition(position.id), [position.id] ); return <tr>...</tr>; }); // After: the compiler handles it function PositionRow({ position }: Props) { const pnl = calculatePnl(position); const handleClose = () => closePosition(position.id); return <tr>...</tr>; }

The code is simpler, easier to read, and performs the same or better.

What you should keep

The compiler is not a silver bullet for trading application performance. Several patterns that are critical for real-time UIs operate outside its scope:

WebSocket buffering and throttling - The compiler optimises the render cycle, not the data ingestion layer. You still need to buffer incoming WebSocket messages and flush on a controlled interval. No amount of automatic memoisation helps if you are calling setState 500 times per second.

Virtualisation - The compiler cannot reduce the number of DOM nodes. If your order book has 1,000 price levels, you still need @tanstack/react-virtual or react-window to render only the visible rows. This is a rendering constraint, not a memoisation problem.

Web Workers for heavy computation - RSI calculations, VWAP aggregations, and large dataset transformations still block the main thread regardless of memoisation. The compiler optimises what React renders, not the cost of the computation itself.

State architecture - A single global store that triggers full-tree re-renders on every price tick is still a problem. The compiler reduces the cost of each re-render, but the architectural principle of splitting high-frequency and low-frequency state into separate stores (Zustand, Jotai) remains important.

Manual useMemo/useCallback as escape hatches - The React team explicitly recommends keeping these hooks available for cases where effect dependencies demand precise control or where the compiler's analysis is insufficient. In a trading app, this might apply to complex subscription management or WebSocket lifecycle hooks.

New APIs that matter for trading

React 19.2 introduces several features beyond the compiler that are relevant to trading UIs:

Activity

The <Activity> component lets you pre-render hidden parts of the UI. In a trading context, this is valuable for:

  • Tab pre-loading - Render the positions tab in the background while the user views the order book. When they switch, the content is already mounted.
  • Instrument switching - Pre-render the next instrument's data view so switching between trading pairs feels instant.
  • State preservation - When a user navigates away from a panel and back, Activity preserves the scroll position, input state, and mounted effects without unmounting.
<Activity mode={activeTab === "positions" ? "visible" : "hidden"}> <PositionsPanel /> </Activity> <Activity mode={activeTab === "orders" ? "visible" : "hidden"}> <OrdersPanel /> </Activity>

Hidden Activity children have their effects unmounted and updates deferred until React is idle, so there is no performance cost to keeping them around.

View Transitions

<ViewTransition> provides declarative animations when UI state changes, using the browser's native startViewTransition API. For trading applications, this is useful for:

  • Animated transitions when switching between instruments or workspaces
  • Smooth layout shifts when panels are resized or rearranged
  • Visual feedback when switching between order form modes (market, limit, stop)

The key constraint is that view transitions should not be applied to high-frequency data updates. Animating every price tick in the order book would be counterproductive. Reserve transitions for user-initiated navigation and layout changes.

DevTools performance tracks

React 19.2 adds custom tracks to Chrome DevTools performance profiles showing what React is working on across different priorities - "blocking" for user interactions, "transition" for startTransition updates. For trading applications, this visibility is invaluable for diagnosing whether a price update is blocking an order submission interaction.

Adopting the compiler

The compiler is compatible with React 17 and up, so you do not need to be on React 19 to start using it. For trading applications, the adoption path is:

  1. Install the Babel plugin - Add babel-plugin-react-compiler to your build pipeline. It must run first in your Babel plugin chain.

  2. Run in lint-only mode first - The compiler ships lint rules in eslint-plugin-react-hooks that flag code patterns the compiler cannot optimise. Fix these before enabling compilation.

  3. Enable per-directory - Start with a single component directory (e.g. your blotter components) and measure the impact before rolling out globally.

  4. Remove manual memoisation gradually - Do not strip all React.memo, useMemo, and useCallback at once. Remove them incrementally and profile after each change to confirm the compiler is covering them.

  5. Keep your data layer intact - Do not remove WebSocket buffering, virtualisation, or Web Workers under the assumption that the compiler will compensate. These solve fundamentally different problems.

The bigger picture

The React Compiler era shifts the performance conversation for trading applications. Previously, a significant portion of frontend engineering effort went into manual memoisation - figuring out which components to wrap in React.memo, which calculations to memoise, which callbacks to stabilise. This was error-prone (a single unstable reference could defeat an entire memoisation chain) and added cognitive overhead to every component.

With the compiler handling this automatically, trading UI teams can focus on the problems that actually require human judgement: data architecture, WebSocket lifecycle management, layout systems, and the domain-specific logic that makes a trading platform useful.

The compiler does not change what makes a trading UI fast. It changes how much effort is required to get there.

Kickstart Your Trading Application

Hedge UI is a React starter kit with production-ready trading components, real-time data handling, and customisable layouts — so you can ship faster.

Get Hedge UI