Skip to content

Conversation

javiercn
Copy link
Member

@javiercn javiercn commented Sep 22, 2025

Ensure Virtualize renders at least OverscanCount items when OverscanCount > MaxItemCount

Description

Issue #63651 reports incorrect behavior when OverscanCount exceeds MaxItemCount: the component could under‑render (large blank area, late loads) because the effective maximum item window was clamped too low, causing excessive “unused capacity” and spacer translation anomalies.

  • Updates Virtualize.cs (CalculateItemDistribution) to elevate the effective MaxItemCount to at least OverscanCount after applying the (legacy) AppContext override and the MaxItemCount parameter.
  • Adds an end-to-end Razor test component VirtualizationLargeOverscan.razor (in BasicTestApp) exercising OverscanCount="200" with MaxItemCount="5".
  • Adds an E2E test method CanElevateEffectiveMaxItemCount_WhenOverscanExceedsMax in VirtualizationTest.cs verifying:
    • At least 200 items render initially (effective max elevated)
    • Stable item count after scroll (no runaway growth or regression below overscan)
  • Registers the new component in Index.razor so the existing mounting infrastructure can locate it.

No public API surface changes; only internal logic and test assets updated.

Fixes #63651

Customer Impact

Addresses an issue with the Aspire dashboard.

Without the fix, apps that (intentionally or accidentally) configure a small MaxItemCount together with a large OverscanCount can observe:

  • Large blank gaps / delayed loading
  • Unintuitive scrolling behavior (spacers reserving space but items not materializing)
  • Potential perception of a frozen list

After the fix, Virtualize behaves predictably: it always renders enough items to satisfy the overscan window while still honoring the safeguard intent of MaxItemCount for realistic configurations.

Regression?

  • Yes
  • No

From 8.x for the aspire case. We don't believe this issue is common outside of the very specific usage Aspire does.

Risk

  • High
  • Medium
  • Low

Justification:

  • Change is a small, isolated conditional raising an internal working value (maxItemCount = OverscanCount when smaller).
  • Does not reduce correctness for normal cases (when MaxItemCount >= OverscanCount, behavior unchanged).
  • Covered by new targeted E2E test.
  • No API contract changes; no serialization / persistence impacts.

Verification

  • Manual (navigated and scrolled virtualization scenarios)
  • Automated (new E2E test passes; existing virtualization test suite still green)

Packaging changes reviewed?

  • Yes
  • No
  • N/A (No packaging / shipping artifact changes; only source + test updates)

@github-actions github-actions bot added the area-blazor Includes: Blazor, Razor Components label Sep 22, 2025
@javiercn javiercn marked this pull request as ready for review September 22, 2025 12:36
@javiercn javiercn requested review from a team and wtgodbe as code owners September 22, 2025 12:36
@Copilot Copilot AI review requested due to automatic review settings September 22, 2025 12:36
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug in the Blazor Virtualize component where OverscanCount > MaxItemCount caused under-rendering with large blank areas and delayed loading. The fix ensures that the effective MaxItemCount is elevated to at least match OverscanCount when needed.

  • Updated CalculateItemDistribution in Virtualize.cs to set effective MaxItemCount to at least OverscanCount
  • Added comprehensive E2E test coverage for the large overscan scenario
  • Created test components to validate the fix behavior

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Components/Web/src/Virtualization/Virtualize.cs Core fix - elevates effective MaxItemCount when OverscanCount exceeds it
src/Components/test/testassets/BasicTestApp/VirtualizationLargeOverscan.razor Test component with OverscanCount=200 and MaxItemCount=5
src/Components/test/E2ETest/Tests/VirtualizationTest.cs E2E test validating at least 200 items render and remain stable after scroll
src/Components/test/testassets/BasicTestApp/Index.razor Registers new test component for E2E infrastructure
src/Components/Samples/BlazorUnitedApp/Pages/VirtualizeTest.razor Sample page demonstrating virtualization with 500 items
src/Components/Samples/BlazorUnitedApp/Shared/NavMenu.razor Navigation link to new virtualize test page
global.json Updates .NET SDK version from rc.1 to rc.2

@javiercn
Copy link
Member Author

/backport to release/10.0

Copy link
Contributor

Started backporting to release/10.0: https://github.com/dotnet/aspnetcore/actions/runs/17915567433

Copy link
Contributor

@javiercn backporting to "release/10.0" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Virtualize test
Using index info to reconstruct a base tree...
M	global.json
Falling back to patching base and 3-way merge...
Auto-merging global.json
CONFLICT (content): Merge conflict in global.json
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 Virtualize test
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

Copy link
Member

@maraf maraf left a comment

Choose a reason for hiding this comment

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

Two nits around the test case, otherwise LGTM 👍

@javiercn javiercn added the * NO MERGE * Do not merge this PR as long as this label is present. label Sep 22, 2025
@javiercn javiercn force-pushed the javiercn/virtualize-max-items branch from 96868c7 to 91bf3c6 Compare September 22, 2025 16:48
@javiercn javiercn removed the * NO MERGE * Do not merge this PR as long as this label is present. label Sep 22, 2025
@javiercn
Copy link
Member Author

/backport to release/10.0

Copy link
Contributor

Started backporting to release/10.0: https://github.com/dotnet/aspnetcore/actions/runs/17922394462

@wtgodbe wtgodbe merged commit ee20ac9 into main Sep 23, 2025
30 checks passed
@wtgodbe wtgodbe deleted the javiercn/virtualize-max-items branch September 23, 2025 03:39
@dotnet-policy-service dotnet-policy-service bot added this to the 11.0-preview1 milestone Sep 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scrolling issue in virtualize control on .NET 9 & 10
4 participants