Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add Model + FieldName overload for InputBase and ValidationMessage to avoid expression parsing #61711

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
nmachek opened this issue Apr 27, 2025 · 1 comment
Open
1 task done
Labels
area-blazor Includes: Blazor, Razor Components
Milestone

Comments

@nmachek
Copy link

nmachek commented Apr 27, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

Currently, Blazor’s InputBase and ValidationMessage components require a ValueExpression (e.g., @(() => Model.Property)) to create a FieldIdentifier.

While very convenient and expressive for developers, this design has measurable runtime costs:

  • Expression parsing is relatively slow, especially when done for many components at once (e.g., large or dynamic forms).
  • Memory allocations for closure objects, captured variables, and parsed trees add additional pressure.
  • On WebAssembly (WASM), where CPU/memory is limited, this cost is even more visible.

Even the internal FieldIdentifier.cs file acknowledges the cost concern:

// It would be great to cache this somehow, but it's unclear there's a reasonable way to do
// so, given that it embeds captured values such as "this". We could consider special-casing
// for "() => something.Member" and building a cache keyed by "something.GetType()" with values
// of type Func<object, object> so we can cheaply map from "something" to "something.Member".

This shows that the Blazor team itself recognized that expression parsing is non-trivial and expensive.

However, caching strategies are difficult because of captured closure values, instance-specific references (this), and type safety.

Describe the solution you'd like

Introduce optional parameters for "Model" and "FieldName" on InputBase and ValidationMessage components.

If developers opt-in, Blazor can completely skip parsing the ValueExpression and build a FieldIdentifier directly.

Example:

<InputText Model="Address" FieldName="Street" />
<ValidationMessage Model="Address" FieldName="Street" />

Behind the scenes, FieldIdentifier can be created like:

new FieldIdentifier(model, fieldName)

No parsing.
No closures.
No slow reflection.

I would have created my own components inheriting from InputBase but I had to provide a dummy ValueExpression so that SetParametersAsync doesn't throw an Exception. Even if I precompute the FieldIdentifier in OnInitialized, I cannot avoid the parsing of ValueExpression in SetParametersAsync.

Additional context

Why this makes sense

  • Backward compatible: Existing @(() => Model.Property) usage remains unchanged.
  • Opt-in optimization: Only those who want max performance need to use Model+FieldName.
  • Zero runtime cost: Initialization of FieldIdentifier happens once during OnInitialized().
  • Helps dynamic UI: Forms generated dynamically would benefit enormously.
  • WASM-friendly: Faster rendering on Blazor WebAssembly scenarios.
  • Simpler for large enterprise forms.

I estimate that bypassing expression parsing and directly accepting Model and FieldName in very large forms (100+ inputs) will improve considerably the user experience on page load while reducing CPU utilization.
Action Estimated cost per field
Parsing expression tree ~1.5 - 2 ms
Creating FieldIdentifier manually < 0.01 ms
Accessing property via instance < 0.001 ms

The risks are very low:

  • No breaking changes: all new functionality would be opt-in.
  • Advanced developers would choose the more verbose but faster path only if they need it.

Conclusion

Adding Model + FieldName overloads for Blazor input components is a small and safe improvement with big performance wins, especially for large or dynamic forms.

It aligns with the optimization hints already considered in the internal source code comments.

🙏 Thanks for considering this optimization!

@ghost ghost added the area-blazor Includes: Blazor, Razor Components label Apr 27, 2025
@nmachek
Copy link
Author

nmachek commented Apr 27, 2025

It would be even simpler to take advantage of the EditContext property available already in InputBase and ValidationMessage as [CascadingParameter]. The FieldIdentifier could be instantiated as
new FieldIdentifier(EditContext.Model, fieldName)
and the components would be less verbose:

<InputText  FieldName="nameof(Model.Street)" />
<ValidationMessage  FieldName="nameof(Model.Street)" />

@maraf maraf added this to the Backlog milestone Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

2 participants