[release/11.0-preview4] Virtualization AnchorMode with variable-height support - #66521
Conversation
…ight support Adds a new AnchorMode parameter to the Virtualize component that controls how the viewport behaves at list edges when items are added dynamically. New API: - VirtualizeAnchorMode enum: None (0), Beginning (1), End (2) [Flags] - Virtualize<TItem>.AnchorMode parameter (default: Beginning) Anchor snapshot/restore mechanism: - JS lazily captures the first visible item's position on every IO callback - After a render that shifts content (prepend/append/redistribution), JS restores the anchored item to its original viewport position using measured DOM positions instead of average-height estimates - Works correctly for both fixed and variable height items - Stale IO callbacks are suppressed after anchor restore to prevent undo Behavior matrix: | Scenario | None | Beginning | End | |---------------------|-------------------|-------------------|-------------------| | Prepend at top | Viewport stable | Shows new items | Viewport stable | | Append at bottom | Viewport stable | Auto-scrolls | Auto-scrolls | | Mid-list changes | Viewport stable | Viewport stable | Viewport stable | | Home/End keys | Works | Works | Works | Contributes to dotnet#65742, dotnet#26943. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tability fixes. - Fix IO suppression race: unified suppressSpacerCallbacks flag persists until next user scroll, preventing IntersectionObserver re-entry from undoing anchor restore scroll compensation. - Fix End+variable-height large append: JS-side wasAtBottom detection in refreshObservedElements starts scroll-to-bottom convergence directly, avoiding unreliable C# race conditions. - Remove stale C# _pendingScrollToBottom branch from RefreshDataCoreAsync that caused false re-engage when user scrolled away from bottom. - Fix prepend ordering: items now appear -10,-9,...,-1 instead of -1,-2,...-10. - Fix LargePrependAtTop test to check for -100 (first item after Reverse). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d properly on expansion.
…for container scroll.
…m the edge + remove drift correction because it was causing sub-pixel shifts.
…llection outside of the item provider call.
…mode should converge for them.
…herwise it's working.
…ems when new param is not provided.
There was a problem hiding this comment.
Pull request overview
Backports Virtualize AnchorMode support (including variable-height stability) to improve viewport behavior when items are dynamically prepended/appended, and adds coverage/tests and tooling to encourage correct usage with ItemsProvider.
Changes:
- Adds new
VirtualizeAnchorModeAPI plusVirtualize<TItem>.AnchorMode, and JS interop support for anchor snapshot/restore. - Updates
Virtualize<TItem>logic for prepend/append detection and viewport stabilization; adds extensive E2E and unit test coverage. - Introduces a Roslyn analyzer warning when
VirtualizeusesItemsProviderwithoutItemComparer, and adds BasicTestApp pages for manual testing.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Components/test/testassets/BasicTestApp/VirtualizationAnchorModeWindowScroll.razor | New manual test page for anchor mode behavior with window scrolling. |
| src/Components/test/testassets/BasicTestApp/VirtualizationAnchorMode.razor | New manual test page for anchor mode behavior in a scroll container. |
| src/Components/test/testassets/BasicTestApp/Index.razor | Adds the new manual test pages to the BasicTestApp selector list. |
| src/Components/test/E2ETest/Tests/VirtualizationTest.cs | Adds/adjusts E2E coverage for anchor modes, prepend/append stability, and window scroll scenarios. |
| src/Components/Web/test/Virtualization/VirtualizeTest.cs | Adds unit tests and updates helpers to validate new anchor mode behaviors. |
| src/Components/Web/src/Virtualization/VirtualizeJsInterop.cs | Extends interop to pass anchor mode on init and expose set/restore APIs. |
| src/Components/Web/src/Virtualization/VirtualizeAnchorMode.cs | Adds the new public enum for anchoring behavior. |
| src/Components/Web/src/Virtualization/Virtualize.cs | Implements AnchorMode/ItemComparer parameters and anchor restore logic. |
| src/Components/Web/src/PublicAPI.Unshipped.txt | Declares new public APIs (AnchorMode, ItemComparer, VirtualizeAnchorMode). |
| src/Components/Web.JS/test/Virtualize.test.ts | Extends export tests to include setAnchorMode and restoreAnchor. |
| src/Components/Web.JS/src/Virtualize.ts | Implements anchor snapshot/restore mechanism and anchor-mode-aware convergence/suppression. |
| src/Components/Analyzers/test/VirtualizeItemComparerAnalyzerTest.cs | Adds analyzer tests for ItemsProvider usage without ItemComparer. |
| src/Components/Analyzers/src/VirtualizeItemComparerAnalyzer.cs | Adds analyzer that warns when ItemsProvider is used without ItemComparer. |
| src/Components/Analyzers/src/Resources.resx | Adds localized strings for the new analyzer diagnostic. |
| src/Components/Analyzers/src/DiagnosticDescriptors.cs | Registers new diagnostic descriptor BL0011. |
…nd detection with a fix for it.
…netcore into backport/pr-66262-to-release/11.0-preview4
|
/ba-g template and IIS test failures unrelated - we don't have Virtualization in templates and this PR didn't touch that part |
|
Approved over email |
|
Hi @ilonatommy. This PR was just approved to be included in the upcoming servicing release. Somebody from the @dotnet/aspnet-build team will get it merged when the branches are open. Until then, please make sure all the CI checks pass and the PR is reviewed. |
|
@ilonatommy ... Would you please edit the title of this because I'd like to link it in the Release Notes? Is "with" the word you want? ... - [release/11.0-preview4] Virtualization AnchorMode with for variable-height support
+ [release/11.0-preview4] Virtualization AnchorMode with variable-height support |
…ragment field - The "What's new in ASP.NET Core in .NET 11" release notes state that Virtualize no longer assumes every item has the same height and adapts to item sizes measured at runtime (dotnet/aspnetcore#66521). Limit the same-height rule to .NET 8 through 10 and keep the single-vertical-stack and spacer rules for every version. - Rename the private RenderFragment field in the example to camelCase (logLine) to match the other private fields in the guidance.
Backport of #66262 to release/11.0-preview4
/cc @ilonatommy
Virtualization
AnchorModewith variable-height supportAdds
VirtualizeAnchorModeparameter and anchor snapshot/restore mechanism for variable-height items.Description
Backport of PR #66262 which adds a new
AnchorModeparameter to theVirtualizecomponent that controls viewport behavior at list edges when items are added dynamically. Uses a measure-based anchor snapshot/restore mechanism that works correctly for both fixed and variable-height items.Fixes #65742
Customer Impact
Enables stable viewport behavior for dynamically updated virtualized lists (chat UIs, news feeds, logs) with variable-height items.
Regression?
Risk
New feature with E2E test coverage.
Verification
Packaging changes reviewed?