C
C#17mo ago
DeaDo

Blazor Wasm: Avoiding frequent & slow rerendering of the component

My client is listening to a websocket who is frequently sending dataobjects with 1 image each to the client. The wasm project should display those dataobjects immediately after receiving them (as a card with a image) This makes the UI very laggy I simply run StateHasChanged each time a new object arrives What is the propper way of doing this?
14 Replies
blinkbat
blinkbat17mo ago
do you have a component for just the card list? and can you show how you're appending the new card?
DeaDo
DeaDo17mo ago
I have a component for the Cardlist and a Component for the Card

@foreach (var item in Items)
{
<ItemCard Item="item" />
}

@foreach (var item in Items)
{
<ItemCard Item="item" />
}
@code{
public List<Item> Items { get; set; } = new List<Item>();

protected override async void OnInitialized()
{
CustomClient.OnReceiveSuccess += OnSuccess;
}

private void Success(object? sender, Item item)
{
Items.Add(item);
StateHasChanged();
}
}
@code{
public List<Item> Items { get; set; } = new List<Item>();

protected override async void OnInitialized()
{
CustomClient.OnReceiveSuccess += OnSuccess;
}

private void Success(object? sender, Item item)
{
Items.Add(item);
StateHasChanged();
}
}
blinkbat
blinkbat17mo ago
this doesnt seem like it would be that slow how often are new items coming in?
DeaDo
DeaDo17mo ago
about 1/s The Images are the problem. If I receive but don't display them, the performance is fine. But if I just show them with a image tag and lazy loading. The UI is blocking. The CSS grow on hover on the Card sometimes has multible seconds delay for example
blinkbat
blinkbat17mo ago
the ui should not be blocked while it fetches the image are they urls or base64
DeaDo
DeaDo17mo ago
base64 :/
blinkbat
blinkbat17mo ago
that might be why any way you could use urls?
DeaDo
DeaDo17mo ago
the images are not static they are provided by the database I don't know how to do it with urls
blinkbat
blinkbat17mo ago
you'd use cloud storage instead of storing the b64
DeaDo
DeaDo16mo ago
Inside the ItemCard - Component:
@if (Item.ImageData != null)
{
string image = $"data:image/png;base64,{Convert.ToBase64String(Item.ImageData)}";
<img src="@image" loading="lazy"/>
}
@if (Item.ImageData != null)
{
string image = $"data:image/png;base64,{Convert.ToBase64String(Item.ImageData)}";
<img src="@image" loading="lazy"/>
}
maybe this is just very bad? what would you recommend in my situation? Could i also use something like a Headless CMS? I saw a few which had very nice features for formatting the frequently uploaded images and that could eventually solve some other problems i have with the content The images are uploaded by the users frequently But there won't be a lot of traffic in general
blinkbat
blinkbat16mo ago
well for one i don't think lazy loading has any bearing when you're using the b64 directly i guess i'd try using your api to put the image in cloud storage and return the payload with the url instead of b64 (and keep lazy load) see if that helps rendering etc
Henkypenky
Henkypenky16mo ago
you don't need to call StateHasChanged you are double rendering most likely
Playboi17
Playboi1716mo ago
Shouldn’t really matter since none of the other items parameters change, they shouldn’t re render. If all ItemCards have their item value populated at Initialization, you could just override ShouldRender to be false.
DeaDo
DeaDo16mo ago
Thank you for your help. Ill try that.