Blazor Performance Diagnostics for Re-Rendering and Execution times.
See original GitHub issueThe Problem:
Blazor Performance problems often arise becaues of too frequent and unintended Re-Renders:
For example:
- Unexpected Parameters changes: A objekt-parameter is recreated in the render loop and causes rerenders because it is a parameter change. (No-nos like passing lambdas as parameters)
- One Child Component for some reason is rerendered 10 times on changes.
- Some component maybe throws unintended events which caues rerenders.
- A costly operation (Rest call) is executed while wating for the task to complete multiple renders happen.
- A REST Call is made in OnParametersSet() or OnAfterRender() and by error this rest call is executed multiple times since unexpected Rerenders.
With one Component this can be debugged with console messages in OnParametersSet() or OnAfterRender, but in case of a complex render three with different components this gets quite compilcated to diagnose Performance Bottlenecks.
Also it is often difficult to see which changes cause rerenders in child components. Or which await calls for for responses from Webservices also cause rerenders between initiating the call and completing the call.
Potential Solution:
Some possiblily / Component / API, which allows globally to trace all OnSetParameters, Renders etc. with execution times, to see if renders happen too frequent, how long it is executed and what caues the bottlenecks.
at first maybe an API to hook into the render events of all components would be maybe already enough. Otherwise I would need make a custom ComponentBase class which traces all Steps like BuildRenderTree() or OnAfterRender().
Example
A example output log
Navigation.Component1 InitalizeAsync() took 100 Milliseconds
Navigation.Component1 Inital Render:
Navigation.Component1 BuildRenderTree() took 10 milliseconds
Navigation.Component1.SubComponent Initalize() took 400 milliseconds
Navigation.Component1 Inital Render:
Navigation.Component1 Render because parameter change.
Navigation.Component1.SubComponent BuildRenderTree() took 10 milliseconds
Navigation.Component1 Render because parameter change.
Navigation.Component1.SubComponent BuildRenderTree() took 10 milliseconds
Navigation.Component1 Render because parameter change.
Navigation.Component1.SubComponent BuildRenderTree() took 10 milliseconds
Navigation.Component1 Render because eventhanlder onclick
Navigation.Component1.SubComponent BuildRenderTree() took 10 milliseconds
A integration into the Performance Monitor is maybe possible in Blazor Server Side but on the Blazor Webassembly side only general Browser tools for Webassembly would be possible. Of which I am not aware of yet.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:8
- Comments:10 (7 by maintainers)
(FYI #40867 is related)
I’ve written an article on the problem of thousands of unnecessary re-renderings and one on my solution (to avoid repetitive yet custom ShouldRender overrides), but it isn’t a perfect approach for sure. Still, it’s better than nothing, and maybe it will help inspire something? I have two other ideas that might help, but I am stuck on how I might implement either given that it might involve the guts of how components work. Would anyone want to talk these ideas over?
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.