Base razor component triggers rerendering when:
- Parent component changes parameters
- If cascading parameters are changed
- Event triggers or one of component event handler is triggered
And skip rerender if :
- All parameters are immutable primitive types and no parameters was changed
ShouldRender
method returns false
Do not call StateHasChanged
everywhere
You should not call this method in such event handlers like OnInitialized, OnInitializedAsync, OnParametersSet, OnParametersSetAsync
because ComponentBase
is resposible for triggering render for such lyfecycle events
@page "/counter-state-1"
<p>
Current count: @currentCount
</p>
<p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>
@code {
private int currentCount = 0;
private async Task IncrementCount()
{
currentCount++;
// Renders here automatically
await Task.Delay(1000);
currentCount++;
StateHasChanged();
await Task.Delay(1000);
currentCount++;
StateHasChanged();
await Task.Delay(1000);
currentCount++;
// Renders here automatically
}
}
Good example from microsoft
Ovveride ShouldRender()
If you path to components mutable types such as custom model types, event callbacks, or RenderFragment values, parent rerendering will cause such components to rerender. To reduce rerendering cost you can let know blazor that this component should not be rerendered.
protected override bool ShouldRender() => false;
This example never rerenders component.
Use virtualize
component
If you are going to show large collections of data, you may consider using the virtualize
component which do not show all your data at one time, but only that which you see on screen. The disadvatage of this component that height should be the same for all items in a collection
Reusable RenderFragments
Big amount of components in hierarchy may cause bad performance. So it is good idea to inline components using RenderFragments
for example:
<div class="chat">
@foreach (var message in messages)
{
@ChatMessageDisplay(message)
}
</div>
@code {
private RenderFragment<ChatMessage> ChatMessageDisplay = message => __builder =>
{
<div class="chat-message">
<span class="author">@message.Author</span>
<span class="text">@message.Text</span>
</div>
};
}
It does not create new component in hierarchy, but allow to reuse as component
Use System.Text.Json
Nowadays, System.Text.Json
is optimized high performance library with small allocation of memory which is best alternative to others Json libs.
Conclusion
There are not all points of render optimization, but first things to check. Alse we do not consider blazor startup time optimization here.