React useLayoutEffect

`useLayoutEffect` runs after React has updated the DOM but before the browser paints the updated screen. It is primarily useful when an effect must measure layout or make a visual DOM adjustment before the user can see the result.

`useLayoutEffect` has the same dependency-array model as `useEffect`, but its timing is different. React runs it after DOM mutations are committed and before the browser paints, so code can inspect the resulting DOM and synchronously apply layout-related changes.

A common use case is measuring an element with APIs such as `getBoundingClientRect()` and then updating state or styles based on that measurement. Because the browser has not painted yet, the user generally does not see an intermediate layout.

The trade-off is that layout effects can block painting. Expensive work inside `useLayoutEffect` can therefore make rendering feel slower. For work that does not need to happen before paint, `useEffect` is generally the better choice.

In server-rendered applications, layout effects also require care because there is no browser DOM during server rendering. Components that depend on browser-only layout information may need to defer that work until client rendering.

Key points

Interview questions

What are the performance risks of `useLayoutEffect`?

A layout effect can delay the browser's opportunity to paint because its work occurs before painting. Expensive JavaScript, repeated layout reads, or unnecessary state updates can therefore increase rendering latency. Layout effects should contain only the work that genuinely needs pre-paint timing. Moving non-visual work to `useEffect` can allow the browser to paint sooner.

When would you use `useLayoutEffect` instead of `useEffect`?

Use `useLayoutEffect` when code must read the DOM or synchronously adjust layout before the browser paints. A typical example is measuring an element and positioning another element from that measurement. For work that does not affect what the user sees during the current paint, `useEffect` is usually preferable. The main reason is to avoid unnecessarily blocking painting.

Why can `useLayoutEffect` prevent visual flicker?

React commits the DOM changes and then runs the layout effect before the browser paints. The effect can measure the new layout and synchronously update state or DOM-related values before that frame becomes visible. This prevents the browser from first showing an incorrect intermediate position. With a normal effect, the initial committed result may be painted before the effect runs.

What problem does `useLayoutEffect` have with server rendering?

Server rendering does not have a browser DOM to measure or manipulate, while layout effects are designed around client-side layout work. Code that depends on `useLayoutEffect` therefore needs to account for the server/client boundary. A common approach is to move browser-dependent behavior into client-only code or conditionally render the component after hydration. The exact solution depends on the rendering architecture being used.