Skip to content

feat(BaseTable): table optimization and adaptive row virtualization - #173

Merged
kseniya57 merged 1 commit into
mainfrom
adaptive-row-virtualization
Sep 8, 2026
Merged

feat(BaseTable): table optimization and adaptive row virtualization#173
kseniya57 merged 1 commit into
mainfrom
adaptive-row-virtualization

Conversation

@kseniya57

@kseniya57 kseniya57 commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves BaseTable performance and stability for large virtualized tables, especially during fast bidirectional scrolling and drag-and-drop reordering.

What changed

  • Added opt-in adaptive row virtualization through adaptiveFlushSync.
  • Added direct DOM updates for row positions and table body size to avoid unnecessary React renders during scrolling.
  • Added bounded, velocity-aware row preloading and deferred row placeholders to prevent visible gaps.
  • Preserved stable row DOM nodes during immutable reordering and tree reparenting.
  • Added optional deferred rendering for horizontally offscreen passive cell content via BaseTable.canDeferOffscreenCellContent.
  • Memoized table rows and cells while keeping table-dependent content up to date.
  • Improved row and column drag auto-scroll coordination and cleanup.
  • Improved useColumnsAutoSize by cancelling stale measurements, serializing React element measurements, and cleaning up measurement roots correctly.
  • Refactored virtualization logic into dedicated hooks and utilities under useAdaptiveVirtualizer.
  • Updated @tanstack/react-virtual from 3.11.2 to 3.14.10.
  • Added documentation and Storybook examples for adaptive virtualization and virtualized tree reordering.

Usage notes

Adaptive virtualization is opt-in. Existing virtualization behavior remains unchanged unless the new options are enabled.

Stable semantic getRowId and getItemKey values are required when rows can be reordered or reparented.

A custom rangeExtractor remains authoritative and disables adaptive range planning.

canDeferOffscreenCellContent should only be enabled for passive content that cannot affect geometry, focus, accessibility, or application state.

@kseniya57 kseniya57 self-assigned this Aug 31, 2026
@kseniya57
kseniya57 requested a review from beliarh as a code owner August 31, 2026 05:45
@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@kseniya57 kseniya57 linked an issue Aug 31, 2026 that may be closed by this pull request
@kseniya57
kseniya57 force-pushed the adaptive-row-virtualization branch 7 times, most recently from 88dc353 to d090961 Compare September 1, 2026 11:53
Comment thread src/hooks/useAdaptiveVirtualizer/utils/applyRowVirtualizerPositions.ts Outdated
Comment thread src/hooks/useAdaptiveVirtualizer/utils/syncRowVirtualizerDom.ts
@kseniya57
kseniya57 force-pushed the adaptive-row-virtualization branch from d090961 to 7b006be Compare September 2, 2026 04:18
@kseniya57 kseniya57 changed the title fix(BaseTable): table optimization and adaptive row virtualization feat(BaseTable): table optimization and adaptive row virtualization Sep 2, 2026
@kseniya57
kseniya57 requested a review from beliarh September 2, 2026 04:19
@kseniya57
kseniya57 force-pushed the adaptive-row-virtualization branch from 7a5cb30 to 0da0d7b Compare September 2, 2026 10:15
beliarh
beliarh previously approved these changes Sep 4, 2026
@kseniya57

kseniya57 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

@beliarh I've added an idle geometry reconciliation pass for virtualized rows src/components/BaseTable/utils/remeasureRenderedRows.ts. TanStack Virtual does not synchronously measure rows mounted during scrolling, and a later measureElement call may return the cached size instead of reading the DOM. If the corresponding ResizeObserver notification is delayed or missed, stale heights remain in the cache, causing gaps or overlapping rows until a window resize triggers a new measurement.
The reconciliation runs only after scrolling stops and only when direct DOM updates are enabled. It validates the row key, index, DOM ownership, and realization state, batches all layout reads, and calls resizeItem only for rows whose actual size differs from the cached value. This keeps layout reads out of the active scroll path.

@kseniya57
kseniya57 force-pushed the adaptive-row-virtualization branch from f6f1c66 to a812124 Compare September 5, 2026 06:09
@kseniya57
kseniya57 merged commit e858105 into main Sep 8, 2026
6 checks passed
@kseniya57
kseniya57 deleted the adaptive-row-virtualization branch September 8, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimizing the row rendering

3 participants