Synchronous Layout Calculations with useLayoutEffect
Synchronous Layout Calculations with useLayoutEffect
React's useEffect is asynchronous and non-blocking: it executes after the browser paints the updated DOM to the screen. While this preserves 60 FPS UI performance for 95% of side effects, it causes visible visual flicker when measuring DOM nodes (e.g., tooltips, popovers, dropdown positions) and updating state before painting. useLayoutEffect runs synchronously before the browser paints.
1. The Rendering Lifecycle: useEffect vs useLayoutEffect
If you position a tooltip dynamically inside useEffect:
- 1The DOM mounts with tooltip at
(0, 0). - 2The browser paints: user briefly sees the tooltip flicker at the top-left corner of the screen for 1 frame.
- 3
useEffectruns, measures the trigger button, and sets coordinates(250, 180). - 4The browser re-paints: tooltip jumps to the correct position.
With useLayoutEffect, the coordinate calculation happens before step 2, preventing any visual jump.
2. Dynamic Tooltip Positioning Example
3. Server-Side Rendering (SSR) Warning
Because useLayoutEffect requires direct access to DOM geometric layout engines (getBoundingClientRect, offsetHeight), calling it during Server-Side Rendering (SSR in Next.js or Node.js) generates a warning:
Isomorphic Layout Effect Solution
To silence this warning in universal codebases, conditionally alias useLayoutEffect to useEffect on the server:
Practice Quiz
External Store Synchronization with useSyncExternalStore
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Deferred Value Updates with useDeferredValue | External Store Synchronization with useSyncExternalStore |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.