Skip to content

Commit db89bfb

Browse files
committed
feat: add useAnimationFrameWithResizeObserver option
1 parent 014586c commit db89bfb

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

docs/api/virtualizer.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,14 @@ isRtl: boolean
258258

259259
Whether to invert horizontal scrolling to support right-to-left language locales.
260260

261+
### `useAnimationFrameWithResizeObserver`
262+
263+
```tsx
264+
useAnimationFrameWithResizeObserver: boolean
265+
```
266+
This option enables wrapping ResizeObserver measurements in requestAnimationFrame for smoother updates and reduced layout thrashing. The default value is `true`.
267+
268+
261269
## Virtualizer Instance
262270

263271
The following properties and methods are available on the virtualizer instance:

packages/virtual-core/src/index.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,21 @@ export const observeElementRect = <T extends Element>(
8484
}
8585

8686
const observer = new targetWindow.ResizeObserver((entries) => {
87-
const entry = entries[0]
88-
if (entry?.borderBoxSize) {
89-
const box = entry.borderBoxSize[0]
90-
if (box) {
91-
handler({ width: box.inlineSize, height: box.blockSize })
92-
return
87+
const run = () => {
88+
const entry = entries[0]
89+
if (entry?.borderBoxSize) {
90+
const box = entry.borderBoxSize[0]
91+
if (box) {
92+
handler({ width: box.inlineSize, height: box.blockSize })
93+
return
94+
}
9395
}
96+
handler(element.getBoundingClientRect())
9497
}
95-
handler(element.getBoundingClientRect())
98+
99+
instance.options.useAnimationFrameWithResizeObserver
100+
? requestAnimationFrame(run)
101+
: run()
96102
})
97103

98104
observer.observe(element, { box: 'border-box' })
@@ -337,6 +343,7 @@ export interface VirtualizerOptions<
337343
useScrollendEvent?: boolean
338344
enabled?: boolean
339345
isRtl?: boolean
346+
useAnimationFrameWithResizeObserver?: boolean
340347
}
341348

342349
export class Virtualizer<
@@ -378,7 +385,12 @@ export class Virtualizer<
378385

379386
return (_ro = new this.targetWindow.ResizeObserver((entries) => {
380387
entries.forEach((entry) => {
381-
this._measureElement(entry.target as TItemElement, entry)
388+
const run = () => {
389+
this._measureElement(entry.target as TItemElement, entry)
390+
}
391+
this.options.useAnimationFrameWithResizeObserver
392+
? requestAnimationFrame(run)
393+
: run()
382394
})
383395
}))
384396
}
@@ -427,6 +439,7 @@ export class Virtualizer<
427439
enabled: true,
428440
isRtl: false,
429441
useScrollendEvent: true,
442+
useAnimationFrameWithResizeObserver: true,
430443
...opts,
431444
}
432445
}

0 commit comments

Comments
 (0)