fix: performance issues with measureElement (#806) · TanStack/virtual@0ad4e6c · GitHub
Skip to content

Commit 0ad4e6c

Browse files
authored
fix: performance issues with measureElement (#806)
* refactor: memoize notify * fix: remove measureElement from VirtualItem * fix: get item from cache in resizeItem * docs: update measureElement signature
1 parent eebc3e7 commit 0ad4e6c

5 files changed

Lines changed: 62 additions & 48 deletions

File tree

‎docs/api/virtual-item.md‎

Lines changed: 1 addition & 2 deletions

‎docs/api/virtualizer.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,13 @@ An optional function that if provided is called when the scrollElement changes a
184184

185185
```tsx
186186
measureElement?: (
187-
el: TItemElement,
188-
instance: Virtualizer<TScrollElement, TItemElement>
187+
element: TItemElement,
188+
entry: ResizeObserverEntry | undefined,
189+
instance: Virtualizer<TScrollElement, TItemElement>,
189190
) => number
190191
```
191192

192-
This optional function is called when the virtualizer needs to dynamically measure the size (width or height) of an item when `virtualItem.measureElement` is called. It's passed the element given when you call `virtualItem.measureElement(TItemElement)` and the virtualizer instance. It should return the size of the element as a `number`.
193+
This optional function is called when the virtualizer needs to dynamically measure the size (width or height) of an item.
193194

194195
> 🧠 You can use `instance.options.horizontal` to determine if the width or height of the item should be measured.
195196

‎examples/lit/dynamic/src/main.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class ColumnVirtualizerDynamic extends LitElement {
167167
<div
168168
data-index="${virtualColumn.index}"
169169
style="position:absolute;top:0;left:0;height:100%;transform:translateX(${virtualColumn.start}px)"
170-
${ref(virtualColumn.measureElement)}
170+
${ref(virtualizer.measureElement)}
171171
class="${virtualColumn.index % 2 === 0
172172
? 'list-item-even'
173173
: 'list-item-odd'}"

‎examples/react/padding/src/main.tsx‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ function RowVirtualizerDynamic({ rows }: { rows: Array<number> }) {
7070
>
7171
{rowVirtualizer.getVirtualItems().map((virtualRow) => (
7272
<div
73-
key={virtualRow.index}
74-
ref={virtualRow.measureElement}
73+
key={virtualRow.key}
74+
data-index={virtualRow.index}
75+
ref={rowVirtualizer.measureElement}
7576
className={virtualRow.index % 2 ? 'ListItemOdd' : 'ListItemEven'}
7677
style={{
7778
position: 'absolute',
@@ -123,8 +124,9 @@ function ColumnVirtualizerDynamic({ columns }: { columns: Array<number> }) {
123124
>
124125
{columnVirtualizer.getVirtualItems().map((virtualColumn) => (
125126
<div
126-
key={virtualColumn.index}
127-
ref={virtualColumn.measureElement}
127+
key={virtualColumn.key}
128+
data-index={virtualColumn.index}
129+
ref={columnVirtualizer.measureElement}
128130
className={
129131
virtualColumn.index % 2 ? 'ListItemOdd' : 'ListItemEven'
130132
}
@@ -161,6 +163,7 @@ function GridVirtualizerDynamic({
161163
estimateSize: () => 50,
162164
paddingStart: 200,
163165
paddingEnd: 200,
166+
indexAttribute: 'data-row-index',
164167
})
165168

166169
const columnVirtualizer = useVirtualizer({
@@ -170,6 +173,7 @@ function GridVirtualizerDynamic({
170173
estimateSize: () => 50,
171174
paddingStart: 200,
172175
paddingEnd: 200,
176+
indexAttribute: 'data-column-index',
173177
})
174178

175179
const [show, setShow] = React.useState(true)
@@ -203,13 +207,15 @@ function GridVirtualizerDynamic({
203207
}}
204208
>
205209
{rowVirtualizer.getVirtualItems().map((virtualRow) => (
206-
<React.Fragment key={virtualRow.index}>
210+
<React.Fragment key={virtualRow.key}>
207211
{columnVirtualizer.getVirtualItems().map((virtualColumn) => (
208212
<div
209-
key={virtualColumn.index}
213+
key={virtualColumn.key}
214+
data-row-index={virtualRow.index}
215+
data-column-index={virtualColumn.index}
210216
ref={(el) => {
211-
virtualRow.measureElement(el)
212-
virtualColumn.measureElement(el)
217+
rowVirtualizer.measureElement(el)
218+
columnVirtualizer.measureElement(el)
213219
}}
214220
className={
215221
virtualColumn.index % 2

‎packages/virtual-core/src/index.ts‎

Lines changed: 42 additions & 34 deletions

0 commit comments

Comments
 (0)