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: significantly reduce form state response size by up to 3x #9388

Merged
merged 29 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ab0885c
removes undefined values from form state response
jacobsfletch Nov 20, 2024
bfe5ba3
removes utility for speed and removes empty errorPaths array
jacobsfletch Nov 20, 2024
56a7e9c
removes isSidebar property from all fields
jacobsfletch Nov 20, 2024
e600b35
only send passesCondition if false
jacobsfletch Nov 20, 2024
2ef71dd
only send valid if false and fieldSchema if explicitly requested
jacobsfletch Nov 20, 2024
f334240
sanitizes nested properties
jacobsfletch Nov 21, 2024
322793b
removes unused customComponents client prop
jacobsfletch Nov 21, 2024
d3dc594
resets generated types in test suites
jacobsfletch Nov 21, 2024
95e4fbc
temporarily adds default valid back in
jacobsfletch Nov 21, 2024
c474cf9
explicitly checks for valid false during field validation on change
jacobsfletch Nov 21, 2024
d9af5b3
Merge branch 'main' into perf/optimize-form-state
jacobsfletch Nov 21, 2024
46e5d9d
adds experimental.optimized flag for backward compatibility
jacobsfletch Nov 21, 2024
3ad295b
fix optional flag
jacobsfletch Nov 21, 2024
4c156ce
puts passesCondition optimization behind flag
jacobsfletch Nov 21, 2024
a23af85
safely access experimental properties
jacobsfletch Nov 21, 2024
06ecb67
adds more flag safety
jacobsfletch Nov 21, 2024
c695d0f
cleanup
jacobsfletch Nov 21, 2024
bec7611
ensures initial page response uses optimized form state as well
jacobsfletch Nov 21, 2024
dd956f1
Merge branch 'main' into perf/optimize-form-state
jacobsfletch Jan 9, 2025
02b96c1
adds experimental flag to payload config itself to make it truly opt-in
jacobsfletch Jan 9, 2025
aa09970
adjust comments
jacobsfletch Jan 9, 2025
cbeea42
safely reads config.admin.compnonents
jacobsfletch Jan 9, 2025
99d1957
adds exp flag to test config
jacobsfletch Jan 9, 2025
c775c97
renames flag to optimizeFormState and removes leftover experimental arg
jacobsfletch Jan 9, 2025
4a7d990
temporarily casts types to avoid writing conditional types
jacobsfletch Jan 13, 2025
28f958e
proper todo flags in jsdocs
jacobsfletch Jan 13, 2025
a564260
ensures custom components object exists for rich text fields to populate
jacobsfletch Jan 13, 2025
0c54b6a
prevents more undefined values from being sent in the rsc responses
jacobsfletch Jan 13, 2025
9d1d630
removes experimental flag
jacobsfletch Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/next/src/utilities/initPage/handleAdminPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function getRouteInfo({
globalConfig = config.globals.find((global) => global.slug === globalSlug)
}

// If the collection is using a custom ID, we need to determine it's type
// If the collection is using a custom ID, we need to determine its type
if (collectionConfig && payload) {
if (payload.collections?.[collectionSlug]?.customIDType) {
idType = payload.collections?.[collectionSlug].customIDType
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/views/Account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export const Account: React.FC<AdminViewProps> = async ({
data,
docPermissions,
docPreferences,
experimental: {
optimized: true,
},
locale: locale?.code,
operation: 'update',
renderAllFields: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/views/CreateFirstUser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export const CreateFirstUserView: React.FC<AdminViewProps> = async ({ initPageRe
data,
docPermissions,
docPreferences,
experimental: {
optimized: true,
},
locale: locale?.code,
operation: 'create',
renderAllFields: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/next/src/views/Document/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ export const renderDocument = async ({
data: doc,
docPermissions,
docPreferences,
experimental: {
optimized: true,
},
fallbackLocale: false,
globalSlug,
locale: locale?.code,
Expand Down
2 changes: 1 addition & 1 deletion packages/payload/src/admin/forms/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
export type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>

export type ClientComponentProps = {
customComponents: FormField['customComponents']
customComponents?: FormField['customComponents']
field: ClientBlock | ClientField | ClientTab
forceRender?: boolean
readOnly?: boolean
Expand Down
21 changes: 18 additions & 3 deletions packages/payload/src/admin/forms/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,20 @@ export type FieldState = {
*/
fieldSchema?: Field
filterOptions?: FilterOptionsResult
initialValue: unknown
initialValue?: unknown
/**
* @deprecated
* This is a legacy property that is no longer used.
* Please use `fieldIsSidebar(field)` from `payload` instead
* Or check `field.admin.position === 'sidebar'` directly.
**/
isSidebar?: boolean
passesCondition?: boolean
requiresRender?: boolean
rows?: Row[]
valid: boolean
valid?: boolean
validate?: Validate
value: unknown
value?: unknown
}

export type FieldStateWithoutComponents = Omit<FieldState, 'customComponents'>
Expand All @@ -68,6 +74,15 @@ export type BuildFormStateArgs = {
data?: Data
docPermissions: SanitizedDocumentPermissions | undefined
docPreferences: DocumentPreferences
experimental?: {
/**
* If true, makes form state as small as possible by omitting unnecessary properties from the response
* Examples include the `isSidebar`, `passesCondition`, or `valid`, properties. See https://github.com/payloadcms/payload/pull/9388.
* In the next major version, this will be the default behavior.
* @default false
**/
optimized: boolean
}
fallbackLocale?: false | TypedLocale
formState?: FormState
id?: number | string
Expand Down
8 changes: 7 additions & 1 deletion packages/payload/src/admin/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,13 @@ export type RenderedField = {
Field: React.ReactNode
indexPath?: string
initialSchemaPath?: string
isSidebar: boolean
/**
* @deprecated
* This is a legacy property that is no longer used.
* Please use `fieldIsSidebar(field)` from `payload` instead
* Or check `field.admin.position === 'sidebar'` directly.
**/
isSidebar?: boolean
path: string
schemaPath: string
type: FieldTypes
Expand Down
9 changes: 1 addition & 8 deletions packages/richtext-lexical/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@
"rootDir": "./src" /* Specify the root folder within your source files. */,
"strict": true
},
"exclude": [
"dist",
"build",
"tests",
"test",
"node_modules",
"eslint.config.js",
],
"exclude": ["dist", "build", "tests", "test", "node_modules", "eslint.config.js"],
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.json"],
"references": [
{ "path": "../payload" },
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/src/forms/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export const Form: React.FC<FormProps> = (props) => {
// Execute server side validations
if (Array.isArray(beforeSubmit)) {
let revalidatedFormState: FormState

const serializableFields = deepCopyObjectSimpleWithoutReactComponents(
contextRef.current.fields,
)
Expand All @@ -241,7 +242,9 @@ export const Form: React.FC<FormProps> = (props) => {
revalidatedFormState = result
}, Promise.resolve())

const isValid = Object.entries(revalidatedFormState).every(([, field]) => field.valid)
const isValid = Object.entries(revalidatedFormState).every(
([, field]) => field.valid !== false,
)

if (!isValid) {
setProcessing(false)
Expand All @@ -268,6 +271,7 @@ export const Form: React.FC<FormProps> = (props) => {
const serializableFields = deepCopyObjectSimpleWithoutReactComponents(
contextRef.current.fields,
)

const data = reduceFieldsToValues(serializableFields, true)

if (overrides) {
Expand Down
Loading