Skip to content

fix: StreamRendering parent with Tabs child doesn't update smoothly #3690

Open
@cdock1029

Description

@cdock1029

🐛 Bug Report

A StreamRendering parent that updates a Param that it passes to a WASM child component doesn't update/rerender appropriately with incremental updates. I'm using an async enumerable; in my repro I slow it way down to illustrate.

💻 Repro or Code Sample

Code Repro Github

Here is the parent weather page that is stream rendered.

Weather.razor

@page "/weather"
@attribute [StreamRendering]

<PageTitle>Weather</PageTitle>

<h1>Weather Page - StreamRendering</h1>

<p>with embedded wasm WeatherComponent:</p>

<p>Data is loaded with async enumerable</p>

<WeatherComponent Forecasts="_forecasts"/>


@code {
    private List<WeatherComponent.WeatherForecast>? _forecasts;

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(400);
        _forecasts = [];
        await foreach (WeatherComponent.WeatherForecast f in LoadAsyncEnumerable())
        {
            _forecasts.Add(f);
            StateHasChanged();
        }
    }

    static async IAsyncEnumerable<WeatherComponent.WeatherForecast> LoadAsyncEnumerable()
    {
        DateOnly startDate = DateOnly.FromDateTime(DateTime.Now);
        var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };

        foreach (int i in Enumerable.Range(1, 8))
        {
            await Task.Delay(100);
            yield return new WeatherComponent.WeatherForecast
            {
                Date = startDate.AddDays(i),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = summaries[Random.Shared.Next(summaries.Length)]
            };
        }
    }

}

Here is the WASM child component. Without the tabs, just the grid by itself, or a vanilla usage of just rendering a plain list, it works fine and updates smoothly as data is streamed in.

With the Tab component un-commented, it renders initially but doesn't handle updates well, flickers until all data is settled.

WeatherComponent.razor

@rendermode @(new InteractiveWebAssemblyRenderMode(true))


@* <FluentTabs @bind-ActiveTabId="@_tabId">
    <FluentTab Label="One" Id="one">
 *@

    <FluentDataGrid Id="weathergrid" Items="@Forecasts?.AsQueryable()" GridTemplateColumns="1fr 1fr 1fr 2fr" Loading="@(Forecasts == null)" TGridItem="WeatherForecast">
        <PropertyColumn Title="Date" Property="@(c => c!.Date)" Align="Align.Start" Format="yyyy-MM-dd"/>
        <PropertyColumn Title="Temp. (C)" Property="@(c => c!.TemperatureC)" Align="Align.Center"/>
        <PropertyColumn Title="Temp. (F)" Property="@(c => c!.TemperatureF)" Align="Align.Center"/>
        <PropertyColumn Title="Summary" Property="@(c => c!.Summary)" Align="Align.End"/>
    </FluentDataGrid>

@*     </FluentTab>
</FluentTabs>
 *@

@code {

    [Parameter]
    public List<WeatherForecast>? Forecasts { get; set; }

    string? _tabId = "one";

    public class WeatherForecast
    {
        public DateOnly Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}

🤔 Expected Behavior

Tabs shouldn't have unique rendering properties in relation to streaming updates.

😯 Current Behavior

Without the tabs:

Without.Tab.mp4

With the tabs:

WithTab.mp4

💁 Possible Solution

I'm guessing it has something to do with JavaScript and web components.

🔦 Context

I'm trying to find the ideal way to do pre-rendering, but avoid flickers and double renders. SSR with Stream rendering as much as possible, with isolated WASM for interactive components that have props passed to them by parents works pretty great, avoiding using a web api on the client as much as possible. Data fetched on server and serialized automatically as [Parameter].

🌍 Your Environment

  • OS & Device: [Windows]
  • Browser [Microsoft Edge]
  • .NET and Fluent UI Blazor library Version [4.11.8, .NET 9]

Metadata

Metadata

Assignees

No one assigned

    Labels

    community:contributionIssue will/can be addressed by community contribution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions