Skip to content

refactor: simplify TreeGrid connector scrollToIndex - #10050

Draft
vursen wants to merge 1 commit into
mainfrom
fix/treegrid-scroll-to-index-page-loading
Draft

refactor: simplify TreeGrid connector scrollToIndex#10050
vursen wants to merge 1 commit into
mainfrom
fix/treegrid-scroll-to-index-page-loading

Conversation

@vursen

@vursen vursen commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Description

Related to #10014
Related to vaadin/web-components#12691

The TreeGrid connector used __pendingScrollToIndexes for two things: to defer a scrollToIndex call until the grid is ready, and to block page loading in _shouldLoadCachePage. The block was only ever needed for the short window in which the old range is cleared while still rendered. It also stayed on whenever a deferred call was not retried or the server request failed, which is how #10014 ended up with a grid that no longer lazy loads. The web component now retries a deferred call even when no rows are rendered (vaadin/web-components#12691), which fixes that issue on its own. This change handles the old range directly and removes the block, so page loading no longer depends on the scroll state at all.

  • Removed the _shouldLoadCachePage override from treeGridConnector.ts, so a pending scrollToIndex no longer prevents page loading
  • Made scrollToIndex resolve the pending page requests right after scrolling to the preloaded range
    • The old rows request their pages again while the new range is being applied. Resolving them after the scroll re-checks the rendered rows against the cache and cancels the debounced request, so no extra range request is sent
  • Added tree-grid-connector-scroll-to-index.test.ts covering scrollToIndex called before and after the grid has rendered
  • Stubbed setViewportRangeByIndexPath with a controllable promise in the shared test helpers and added the FlowTreeGrid type there

Type of change

  • Refactor

@vursen vursen changed the title fix: keep TreeGrid lazy loading after deferred scrollToIndex fix: keep TreeGrid lazy loading working after deferred scrollToIndex Sep 8, 2026
@vursen
vursen marked this pull request as ready for review September 8, 2026 09:00
@vursen

vursen commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

The fix can be backported to 25.3 as is, but backporting to 25.2 and 25.1 would require a slightly different solution because there is no $connector.resolvePendingRequests() in those versions.

@vursen
vursen force-pushed the fix/treegrid-scroll-to-index-page-loading branch from 601ee32 to 308c01c Compare September 8, 2026 09:02

@vaadin-review-bot vaadin-review-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes — left 1 comment.

Finding
⚠️ Page loads are now also unblocked while the server request is in flight, so a competing setViewportRange can undo the preload

@@ -55,7 +46,12 @@ function initLazy(grid: FlowTreeGrid) {
const flatIndex = await grid.$server.setViewportRangeByIndexPath(indexes, padding);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Page loads are now also unblocked while the server request is in flight, so a competing setViewportRange can undo the preload

The new resolvePendingCallbacks() only cleans up requests that exist after the response arrives. Nothing prevents a request from being sent during the round trip anymore.

If the user scrolls while the request is in flight, the patched __updateVirtualizerElement prefetches the fetch-range edges, which starts a page load and arms the 150 ms request debouncer. When the response takes longer than that, the client sends setViewportRange for the old position. On the server this replaces the active range that setViewportRangeByIndexPath just preloaded, so the target range gets cleared and the grid scrolls to blank rows before re-fetching.

Only the fast path is confirmed to be safe: if the response lands first, the new cleanup cancels the debouncer. Both new tests resolve the promise immediately, so the slow-response window is untested.

treeGridConnector.ts:46 · correctness

@vursen vursen Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue isn't serious: the expected viewport will just get re-requested after scrolling, resulting in one extra round trip. Besides, fixing that was never the goal of the original solution.

@vursen
vursen force-pushed the fix/treegrid-scroll-to-index-page-loading branch from 308c01c to 0beef38 Compare September 8, 2026 09:16

/** The Flow grid element */
export type FlowGrid = Grid<Item> & FlowGridInternals;
export type FlowGrid = FlowGridInternals & Grid<Item>;

@vursen vursen Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Changing the order makes FlowGridInternals (and FlowTreeGridInternals) take priority over Grid<Item>'s properties

@vursen
vursen force-pushed the fix/treegrid-scroll-to-index-page-loading branch 2 times, most recently from 3aa73ef to 5ed4ebe Compare September 8, 2026 09:24
$server: GridServer;
} & ConnectorFlowGrid & {
_flatSize: number;
_updateItem: (index: number, item: Item) => void;

@vursen vursen Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: _updateItem was left out because of no usages.

});
});

describe('initially non-empty data set', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does exactly the same as should run the deferred scroll when the data set becomes non-empty

@vursen

vursen commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

This fix kind of solves the reported issue, but I also wonder if it's correct that the grid attempts to scroll to an index after first being rendered with an empty data set and then a non-empty one.

@vursen
vursen marked this pull request as draft September 8, 2026 12:45
The connector blocked page loading while a scrollToIndex call was
pending so the old range would not be re-requested while the preloaded
range was applied. Resolving the stale requests right after the scroll
handles that directly, so pending scrolls no longer affect page loading.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vursen
vursen force-pushed the fix/treegrid-scroll-to-index-page-loading branch from 5ed4ebe to 8a34212 Compare September 9, 2026 06:12
@vursen vursen changed the title fix: keep TreeGrid lazy loading working after deferred scrollToIndex refactor: simplify TreeGrid connector scrollToIndex Sep 9, 2026
@sonarqubecloud

sonarqubecloud Bot commented Sep 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants