Optimize RenderBatchWriter for empty diffs
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
If we have a component that creates an empty diff when re-rendering, i.e. there was no change in the resulting markup, this empty diff is still sent to the server and takes up a certain size in the serialized data.
For example, consider this component:
@Value.DayOfWeek
@code {
[Parameter]
public DateTime Value { get; set; }
}
Render the above component 1000 times:
@page "/"
<button @onclick="@(StateHasChanged)">Render</button>
<br />
@for (var i = 0; i < 1000; i++)
{
<Component Value="DateTime.Now" />
}
Click the “Render” button.
Despite the fact that the resulting markup does not change (it changes once every 24 hours), 12 kB of data is sent to the server:
It can be seen that the data sent is very “sparse”:
This particular case could of course be optimized using the ShouldRender method. However, in general it doesn’t make sense (at least I think so) to send an empty diff to the client.
Describe the solution you’d like
Modify the int Write(in ArrayRange<RenderTreeDiff> diffs)
method in RenderBatchWriter
to ignore empty diffs.
Additional context
No response
Issue Analytics
- State:
- Created 9 months ago
- Reactions:1
- Comments:6 (5 by maintainers)
Thanks for the info.
I’ve investigated and it does seem like we could omit the empty diffs from the batch. We could omit it at the serialization stage (as you suggested) or perhaps even change
ComponentState.RenderIntoBatch
not to add the diff to the batch in the first place if it’s empty. This would require some very careful consideration to make sure it doesn’t violate any other assumptions around how the state is managed, cleanup is performed, etc. The reason we haven’t done this in the past is that we didn’t consider empty diffs to take up much space, and it seemed like a rather artificial case to be producing thousands of them. But perhaps your UI is different.As a caution, though - it wouldn’t help if your component contained any event handlers, since on each render, they produce different event handler delegates and therefore need updated event handler IDs. In other words, components with event handlers won’t produce empty diffs in most cases, even if you don’t see any visible change to the rendered UI.
I’ll mark this as a backlog item since we have other things to work on more urgently. If this continues to receive community feedback its prioritisation could increase.
One other thing that might help in your case is https://github.com/dotnet/aspnetcore/issues/35897. Once this is implemented in .NET 8, the compression should reduce the bandwidth impact of these repeated empty blocks dramatically. This might have enough of an impact that the empty diffs become irrelevant in practice (though I still agree with the idea of omitting them in principle).
We’ve moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.