Files
payloadcms/test/buildConfigWithDefaults.ts
Jacob Fletcher 31ae27b67d perf: significantly reduce form state response size by up to 3x (#9388)
This significantly optimizes the form state, reducing its size by up to
more than 3x and improving overall response times. This change also has
rolling effects on initial page size as well, where the initial state
for the entire form is sent through the request. To achieve this, we do
the following:
- Remove `$undefined` strings that are potentially attached to
properties like `value`, `initialValue`, `fieldSchema`, etc.
- Remove unnecessary properties like empty `errorPaths` arrays and empty
`customComponents` objects, which only need to exist if used
- Remove unnecessary properties like `valid`, `passesCondition`, etc.
which only need to be returned if explicitly `false`
- Remove unused properties like `isSidebar`, which simply don't need to
exist at all, as they can be easily calculated during render

## Results

The following results were gathered by booting up each test suite listed
below using the existing seed data, navigating to a document in the
relevant collection, then typing a single letter into the noted field in
order to invoke new form-state. The result is then saved to the file
system for comparison.

| Test Suite | Collection | Field | Before | After | Percentage Change |
|------|------|---------|--------|--------|--------|
| `field-perf` | `blocks-collection` | `layout.0.field1` | 227kB | 110
kB | ~52% smaller |
| `fields` | `array-fields` | `items.0.text` | 14 kB | 4 kB | ~72%
smaller |
| `fields` | `block-fields` | `blocks.0.richText` | 25 kB | 14 kB | ~44%
smaller |
2025-01-14 10:45:54 -05:00

182 lines
4.4 KiB
TypeScript

import type { Config, SanitizedConfig } from 'payload'
import {
AlignFeature,
BlockquoteFeature,
BlocksFeature,
BoldFeature,
ChecklistFeature,
HeadingFeature,
IndentFeature,
InlineCodeFeature,
InlineToolbarFeature,
ItalicFeature,
lexicalEditor,
LinkFeature,
OrderedListFeature,
ParagraphFeature,
RelationshipFeature,
StrikethroughFeature,
SubscriptFeature,
SuperscriptFeature,
TreeViewFeature,
UnderlineFeature,
UnorderedListFeature,
UploadFeature,
} from '@payloadcms/richtext-lexical'
// import { slateEditor } from '@payloadcms/richtext-slate'
import { buildConfig } from 'payload'
import { de } from 'payload/i18n/de'
import { en } from 'payload/i18n/en'
import { es } from 'payload/i18n/es'
import sharp from 'sharp'
import { databaseAdapter } from './databaseAdapter.js'
import { reInitEndpoint } from './helpers/reInit.js'
import { localAPIEndpoint } from './helpers/sdk/endpoint.js'
import { testEmailAdapter } from './testEmailAdapter.js'
// process.env.POSTGRES_URL = 'postgres://postgres:postgres@127.0.0.1:5432/payloadtests'
// process.env.PAYLOAD_DATABASE = 'postgres'
// process.env.PAYLOAD_DATABASE = 'sqlite'
export async function buildConfigWithDefaults(
testConfig?: Partial<Config>,
options?: {
disableAutoLogin?: boolean
},
): Promise<SanitizedConfig> {
const config: Config = {
db: databaseAdapter,
editor: lexicalEditor({
features: [
ParagraphFeature(),
RelationshipFeature(),
LinkFeature({
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'description',
type: 'text',
},
],
}),
ChecklistFeature(),
UnorderedListFeature(),
OrderedListFeature(),
AlignFeature(),
BlockquoteFeature(),
BoldFeature(),
ItalicFeature(),
UploadFeature({
collections: {
media: {
fields: [
{
name: 'alt',
type: 'text',
},
],
},
},
}),
UnderlineFeature(),
StrikethroughFeature(),
SubscriptFeature(),
SuperscriptFeature(),
InlineCodeFeature(),
InlineToolbarFeature(),
TreeViewFeature(),
HeadingFeature(),
IndentFeature(),
BlocksFeature({
blocks: [
{
slug: 'myBlock',
fields: [
{
name: 'someText',
type: 'text',
},
{
name: 'someTextRequired',
type: 'text',
required: true,
},
{
name: 'radios',
type: 'radio',
options: [
{
label: 'Option 1',
value: 'option1',
},
{
label: 'Option 2',
value: 'option2',
},
{
label: 'Option 3',
value: 'option3',
},
],
validate: (value) => {
return value !== 'option2' ? true : 'Cannot be option2'
},
},
],
},
],
}),
],
}),
email: testEmailAdapter,
endpoints: [localAPIEndpoint, reInitEndpoint],
secret: 'TEST_SECRET',
sharp,
telemetry: false,
...testConfig,
i18n: {
supportedLanguages: {
de,
en,
es,
},
...(testConfig?.i18n || {}),
},
typescript: {
declare: {
ignoreTSError: true,
},
...testConfig?.typescript,
},
}
if (!config.admin) {
config.admin = {}
}
config.admin.experimental = {
...(config.admin.experimental || {}),
optimizeFormState: true,
}
if (config.admin.autoLogin === undefined) {
config.admin.autoLogin =
process.env.PAYLOAD_PUBLIC_DISABLE_AUTO_LOGIN === 'true' || options?.disableAutoLogin
? false
: {
email: 'dev@payloadcms.com',
}
}
if (process.env.PAYLOAD_DISABLE_ADMIN === 'true') {
if (typeof config.admin !== 'object') {
config.admin = {}
}
config.admin.disable = true
}
return await buildConfig(config)
}