Skip to content

perf(ui): skip rendering custom field components hidden by admin.condition#16780

Draft
jacobsfletch wants to merge 9 commits into
mainfrom
perf/server-component-rendering-conditions
Draft

perf(ui): skip rendering custom field components hidden by admin.condition#16780
jacobsfletch wants to merge 9 commits into
mainfrom
perf/server-component-rendering-conditions

Conversation

@jacobsfletch
Copy link
Copy Markdown
Member

@jacobsfletch jacobsfletch commented May 28, 2026

Form state was eagerly rendering custom components even when the field's admin.condition evaluates to false. The rendered React component was only being hidden client-side, but should have deferred rendering entirely.

This has potentially serious performance implications for two reasons:

  1. Rendering overhead. Despite not mounting to the DOM, custom components still render prematurely, executing potentially expensive tasks like querying the database, etc.
  2. Hidden fields still receive full recursion. Nested fields schemas are still traversed, build state, and resolve their filter options, etc. This includes the rendering step mentioned above.

Now, custom server components DO NOT render unless they pass conditions, as expected. Custom components will now only render if they will be mounted to the page.

Before:

Screen.Recording.2026-05-29.at.10.21.27.AM.mp4

After:

Screen.Recording.2026-05-29.at.10.19.26.AM.mp4

… admin.condition

Initial form-state build was eagerly rendering every field's custom
components (Field, BeforeInput, AfterInput, Description, Error, Label,
RowLabel), including server components, even when the field's
admin.condition resolved false. The rendered React element was baked
into fieldState.customComponents and only hidden client-side by
WatchCondition — work was already done.

Gate the renderFieldFn call in addFieldStatePromise on
`passesCondition !== false`. When the condition later flips true via
onChange, lastRenderedPath is undefined so renderField produces a fresh
element with a current timestamp.

Note: inline function conditions only. Path-valued string refs
(`./Path#export`) are not resolved server-side in iterateFields yet —
those still pre-render.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖
This PR introduced no changes to the esbuild bundle! 🙌

@jacobsfletch jacobsfletch changed the title perf(ui): skip rendering custom field components for fields hidden by admin.condition perf(ui): skip rendering custom field components that fail admin.condition May 28, 2026
@jacobsfletch jacobsfletch changed the title perf(ui): skip rendering custom field components that fail admin.condition perf(ui): skip rendering custom field components hidden by admin.condition May 28, 2026
…s collection

Keeps base Posts collection from accruing condition-specific fixtures.
Cleaner than matching against a magic title string.
…n.condition

Previously only the render call was gated on passesCondition; the switch
still ran filterOptions resolves (DB queries on relationship/upload),
blocks validation, and full recursion into hidden subtrees. Add an
early-exit guard so a failing condition writes a minimal state entry and
returns, skipping access checks, validation, switch processing,
filterOptions, and child iteration. The client re-requests form state on
condition flips, so the minimal entry is sufficient.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant