Skip to content
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

perf: only validate filter options on submit #10738

Merged
merged 6 commits into from
Jan 23, 2025

Conversation

jacobsfletch
Copy link
Member

@jacobsfletch jacobsfletch commented Jan 22, 2025

Field validations currently run very often, such as within form state on type. This can lead to serious performance implications within the admin panel if those validation functions are async, especially if they perform expensive database queries. One glaring example of this is how all relationship and upload fields perform a database lookup in order to evaluate that the given value(s) satisfy the defined filter options. If the field is polymorphic, this can happen multiple times over, one for each collection. Similarly, custom validation functions might also perform expensive tasks, something that Payload has no control over.

The fix here is two-fold. First, we now provide a new event arg to all validate functions that allow you to opt-in to performing expensive operations only when documents are submitted, and fallback to significantly more performant validations as form state is generated. This new pattern will be the new default for relationship and upload fields, however, any custom validation functions will need to be implemented in this way in order to take advantage of it. Here's what that might look like:

[
  // ...
  {
    name: 'text'
    type: 'text',
    validate: async (value, { event }) => {
      if (event === 'onChange') {
        // Do something highly performant here
        return true
      }
      
      // Do something more expensive here
      return true
    }
  }
]

The second part of this is to only run validations after the form as been submitted, and then every change event thereafter. This work is being done in #10580.

@jacobsfletch jacobsfletch changed the title perf: does not validate filter options until submit perf: only validate filter options on submit Jan 22, 2025
@jacobsfletch jacobsfletch force-pushed the perf/validate-filter-options branch from eb194d6 to 61f3010 Compare January 23, 2025 15:13
Copy link
Contributor

@DanRibbens DanRibbens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!
As we discussed, make sure autosave still works as intended with this new feature and add an e2e test or two and merge.

@jacobsfletch jacobsfletch requested a review from denolfe as a code owner January 23, 2025 17:29
@jacobsfletch jacobsfletch merged commit a05240a into main Jan 23, 2025
69 checks passed
@jacobsfletch jacobsfletch deleted the perf/validate-filter-options branch January 23, 2025 20:10
jacobsfletch added a commit that referenced this pull request Jan 27, 2025
Field validations can be expensive, especially custom validations that
are async or highly complex. This can lead to slow form state response
times when generating form state for many such fields. Ideally, we only
run validations on fields whose values have changed. This is not
possible, however, because field validation functions might reference
_other_ field values with their args, and there is no good way of
detecting exactly which fields should run in this case. The next best
thing here is to only run validations _after the form has been
submitted_, and then every `onChange` event thereafter until a
successful submit has taken place. This is an elegant solution because
we currently don't _render_ field errors until submission anyway.

This change will significantly speed up form state response times, at
least until the form has been submitted. From then on, all field
validations will run regardless, just as they do now. If custom
validations continue to slow down form state response times, there is a
new `event` arg introduced in #10738 that can be used to control whether
heavy operations occur on change or on submit.

Related: #10638
Copy link
Contributor

🚀 This is included in version v3.20.0

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.

2 participants