Skip to content

[Blazor] Detecting which parameters have changed #32163

Closed
@daniel-p-tech

Description

@daniel-p-tech

Hi,

I am looking at an efficient way to optimize redundant rendering of complex reusable components (e.g. grid).

Here's a rough draft of the approach that I'm considering:

        protected bool m_shouldRender = false;

        protected override void OnParametersSet()
        {
            if (PrimitiveDataTypeParametersChanged() || ReferenceParametersChanged())
            {
                m_shouldRender = true;
            }
        }

        protected override bool ShouldRender()
        {
            if (m_shouldRender == true)
            {
                m_shouldRender = false;
                return true;
            }

            return false;
        }

The idea is that the component will be rendered only if any of the parameter values have changed. According to https://docs.microsoft.com/en-us/aspnet/core/blazor/webassembly-performance-best-practices?view=aspnetcore-5.0#avoid-unnecessary-rendering-of-component-subtrees guidance, the framework is already detecting PrimitiveDataTypeParametersChanged condition - if a component consists only of primitive data type parameters that have not changed, OnParametersSet is not called to begin with.

I want to avoid declaring a member field for each parameter to track if it has changed - this is an error prone approach and makes the code look rather cumbersome. Another approach is to use reflection to list all parameter properties and store their values in a dictionary - but it does require some additional CPU cycles that I'd like to avoid - clearly Blazor must be doing something similar internally that I'd like to take advantage of. Is this possible? If not, can you show me the lines in source code that perform this check?

With respect to complex data types (references), I'm OK with storing their previous values internally. Consumers of my components will understand that if any of the properties of reference parameters change, they will need to call a public Render method that will then call StateHasChanged. Practically speaking, this will only be needed in scenarios such as adding a new row to a grid that is not bound to ObservableCollection - it's an inconvenience that I'm willing to accept.

I would really prefer not to even bother with this approach, but as various tickets indicate, unnecessary rendering of components is a problem.

Thank you for your help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✔️ Resolution: AnsweredResolved because the question asked by the original author has been answered.Status: Resolvedarea-blazorIncludes: Blazor, Razor Componentsfeature-renderingFeatures dealing with how blazor renders components

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions