You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/api/virtualizer.md
+18-3Lines changed: 18 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -136,7 +136,9 @@ The position where the list is scrolled to on render. This is useful if you are
136
136
getItemKey?: (index:number) =>Key
137
137
```
138
138
139
-
This function is passed the index of each item and should return a unique key for that item. The default functionality of this function is to return the index of the item, but you should override this when possible to return a unique identifier for each item across the entire set. This function should be memoized to prevent unnecessary re-renders.
139
+
This function is passed the index of each item and should return a unique key for that item. The default functionality of this function is to return the index of the item, but you should override this when possible to return a unique identifier for each item across the entire set.
140
+
141
+
**Important:** In React (and similar reactive frameworks), this function **must be memoized** (e.g., using `useCallback`) to prevent infinite re-render loops that will crash your application. Without memoization, the virtualizer will detect the function reference change on every render and trigger measurement recalculation, which causes another render, creating an infinite loop.
140
142
141
143
### `rangeExtractor`
142
144
@@ -266,9 +268,22 @@ Whether to invert horizontal scrolling to support right-to-left language locales
266
268
useAnimationFrameWithResizeObserver: boolean
267
269
```
268
270
269
-
This option enables wrapping ResizeObserver measurements in requestAnimationFrame for smoother updates and reduced layout thrashing. The default value is `false`.
271
+
**Default:**`false`
272
+
273
+
When enabled, defers ResizeObserver measurement processing to the next animation frame using `requestAnimationFrame`.
274
+
275
+
**Important:** This option typically **should not be enabled** in most cases. ResizeObserver callbacks already execute at an optimal time in the browser's rendering pipeline (after layout, before paint), and the measurements provided in the callback are pre-computed by the browser without causing additional reflows.
276
+
277
+
**Potential use cases:**
278
+
- If you're performing heavy DOM mutations in response to size changes and want to batch them with the next render cycle
279
+
- As a workaround for the "ResizeObserver loop completed with undelivered notifications" error (though this usually indicates a deeper issue that should be fixed)
280
+
281
+
**Tradeoffs:**
282
+
-**Adds ~16ms delay:** Measurements are deferred to the next frame, which can cause visual artifacts, stale measurements, or slower time-to-interactive
283
+
-**No batching benefit:** ResizeObserver already batches multiple element resizes into a single callback
284
+
-**Defeats optimization:** The browser has already computed the measurements synchronously; deferring them provides no performance benefit for reading values
270
285
271
-
It helps prevent the "ResizeObserver loop completed with undelivered notifications" error by ensuring that measurements align with the rendering cycle. This can improve performance and reduce UI jitter, especially when resizing elements dynamically. However, since ResizeObserver already runs asynchronously, adding requestAnimationFrame may introduce a slight delay in measurements, which could be noticeable in some cases. If resizing operations are lightweight and do not cause reflows, enabling this option may not provide significant benefits.
286
+
Only enable this option if you have a specific reason and have measured that it improves your use case.
0 commit comments