Skip to content

[dev-v5] FluentOverflow MaxRenderedItems does not limit rendered child elements #5249

Description

Summary

Issue #4949 requested a MaxRenderedItems option that prevents large FluentOverflow collections from rendering every item into the browser DOM. It was closed as completed by #4961.

The v5 implementation does not currently enforce the limit during Blazor rendering. It renders @ChildContent unconditionally and passes MaxRenderedItems to the web component. TypeScript then uses the value only when building the overflow-item collection returned to Blazor.

As a result, MaxRenderedItems limits ItemsOverflow and the JS-to-.NET event payload, but all child components are still rendered by Blazor, sent to the browser, inserted into the DOM, and measured by JavaScript.

Current behavior

FluentOverflow.razor renders the complete fragment:

@ChildContent

The TypeScript implementation discovers and measures every matching child:

const allItems = Array.from(container.querySelectorAll<OverflowElement>(localQuerySelector));

MaxRenderedItems is applied later, while constructing the returned overflow records:

if (!unlimited && overflowItems.length >= maxRenderedItems) {
  break;
}

For example, rendering 500 items with MaxRenderedItems="20" still creates and measures 500 DOM elements. Only the ItemsOverflow payload is capped at 20.

This leaves the performance problem from #4949 unresolved. In Blazor Server, a sufficiently expensive layout can stop the client from processing render updates until SignalR backpressure terminates the connection.

Expected behavior

There should be an opt-in way to:

  1. Limit how many overflow-managed items Blazor renders and sends to the browser.
  2. Treat items beyond that limit as pre-overflowed.
  3. Include pre-overflowed items in the total overflow count.
  4. Make the underlying data for pre-overflowed items available to the overflow template.
  5. Preserve the current unlimited ChildContent behavior by default.

API constraint

The existing ChildContent parameter is an opaque RenderFragment. FluentOverflow cannot enumerate it, associate rendered nodes with source values, or apply Take(MaxRenderedItems) to it. Limiting the fragment itself would also lose the omitted item data and produce an incorrect overflow count.

Possible improvement

Add a data-driven, strongly typed overflow API, either on a generic component or a companion component. For example:

<FluentOverflow TItem="ResourceUrl"
                Items="@urls"
                MaxRenderedItems="20">
    <ItemTemplate Context="url">
        <FluentBadge>@url.DisplayName</FluentBadge>
    </ItemTemplate>
    <OverflowTemplate Context="overflow">
        @foreach (var url in overflow.Items)
        {
            <FluentBadge>@url.DisplayName</FluentBadge>
        }
    </OverflowTemplate>
</FluentOverflow>

With this model, Blazor can render only the first 20 item templates for browser measurement and retain the remaining source items as pre-overflowed data. The existing direct ChildContent API can remain available for arbitrary markup, with its current payload-only semantics documented explicitly.

The exact API shape is open for discussion. Another option is a dedicated virtualized/data-bound overflow component so MaxRenderedItems does not have two different meanings.

Acceptance criteria

  • Given 100 data-bound items and a DOM render limit of 10, no more than 10 managed item elements are initially rendered, excluding fixed framework elements such as the More button.
  • OverflowCount includes both measured overflow items and the 90 items omitted from the DOM.
  • The overflow template can render or otherwise access the omitted item data.
  • Resizing continues to recalculate overflow among the rendered measurement set.
  • Existing ChildContent usage remains backward compatible.
  • Documentation clearly distinguishes the DOM render limit from the JS-to-.NET payload limit.

Activity

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

Metadata

Metadata

Labels

status:needs-investigationNeeds additional investigationv5For the next major version

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions