Skip to content

Commit

Permalink
Merge pull request #3506 from udecode/fix/perf
Browse files Browse the repository at this point in the history
Plate 38: Performance optimization
  • Loading branch information
zbeyens authored Sep 11, 2024
2 parents 068cfc7 + 61c6e8f commit 97fc0e0
Show file tree
Hide file tree
Showing 24 changed files with 519 additions and 330 deletions.
41 changes: 41 additions & 0 deletions .changeset/big-cameras-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
'@udecode/plate-core': major
---

- Change `plugin.options` merging behavior from deep merge to shallow merge.
- This affects `.extend()`, `.configure()`, and other methods that modify plugin options.
- This update addresses a **performance regression** introduced in v37 that affected editor creation.

Before:

```ts
const plugin = createSlatePlugin({
key: 'test',
options: { nested: { a: 1 } },
}).extend({
options: { nested: { b: 1 } },
});

// Result: { nested: { a: 1, b: 1 } }
```

After:

```ts
const plugin = createSlatePlugin({
key: 'test',
options: { nested: { a: 1 } },
}).extend(({ getOptions }) => ({
options: {
...getOptions(),
nested: { ...getOptions().nested, b: 1 },
},
}));

// Result: { nested: { a: 1, b: 1 } }
```

Migration:

- If you're using nested options and want to preserve the previous behavior, you need to manually spread both the top-level options and the nested objects.
- If you're not using nested options, no changes are required.
2 changes: 2 additions & 0 deletions apps/www/content/docs/editor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ const editor = createPlateEditor({
});
```

Note that normalization may take a few dozen milliseconds for large documents, such as the playground value.

### Auto-selection

Configure the editor to automatically select a range:
Expand Down
2 changes: 2 additions & 0 deletions apps/www/content/docs/plugin-methods.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ description: Explore the various methods available for extending Plate plugins.

## Configuration Methods

When extending plugins, all properties are deeply merged by default, with two exceptions: arrays are replaced entirely, and the `options` object is shallow merged.

### .configure

The `.configure` method allows you to override the plugin's configuration.
Expand Down
8 changes: 6 additions & 2 deletions apps/www/src/lib/plate/demo/values/tableValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ export const createTable = (spanning?: boolean): any => (
</hp>
</htd>
<htd>
<hp></hp>
<hp>
<htext />
</hp>
</htd>
<htd>
<hp></hp>
<hp>
<htext />
</hp>
</htd>
<htd>
<hp>No</hp>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from 'react';

import { BasicElementsPlugin } from '@udecode/plate-basic-elements/react';
import { BasicMarksPlugin } from '@udecode/plate-basic-marks/react';
import { Plate, usePlateEditor } from '@udecode/plate-common/react';

import { editableProps } from '@/plate/demo/editableProps';
import { PlateUI } from '@/plate/demo/plate-ui';
import { createMultiEditorsValue } from '@/plate/demo/values/createMultiEditorsValue';
import { Editor } from '@/registry/default/plate-ui/editor';

Expand All @@ -14,8 +11,8 @@ const values = createMultiEditorsValue();
function WithPlate({ id, value }: any) {
const editor = usePlateEditor({
id,
override: { components: PlateUI },
plugins: [BasicElementsPlugin, BasicMarksPlugin],
// override: { components: PlateUI },
// plugins: [BasicElementsPlugin, BasicMarksPlugin],
value,
});

Expand Down
5 changes: 3 additions & 2 deletions apps/www/src/registry/default/example/playground-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {

const editorId = id || 'playground-' + key;

return usePlateEditor(
const a = usePlateEditor(
{
id: editorId,
override: {
Expand Down Expand Up @@ -310,11 +310,12 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {
enabled: process.env.NODE_ENV !== 'production',
}),
],
shouldNormalizeEditor: true,
value: value,
},
[]
);

return a;
};

export default function PlaygroundDemo({
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/internal/mergePlugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import mergeWith from 'lodash/mergeWith.js';

import type { SlatePlugin } from '../lib';

export function mergePlugins<T>(basePlugin: T, ...sourcePlugins: any[]): T {
return mergeWith(
{},
basePlugin,
...sourcePlugins,
(objValue: unknown, srcValue: unknown, key: keyof SlatePlugin) => {
// Overwrite array (including plugins) without cloning
if (Array.isArray(srcValue)) {
return srcValue;
}
// Shallow merge options
if (key === 'options') {
return { ...(objValue as any), ...(srcValue as any) };
}
}
);
}
14 changes: 0 additions & 14 deletions packages/core/src/internal/mergeWithoutArray.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/core/src/lib/plugin/SlatePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export type SlatePluginMethods<C extends AnyPluginConfig = PluginConfig> = {
| SlatePluginConfig<any, InferOptions<P>, InferApi<P>, InferTransforms<P>>
) => SlatePlugin<C>;

create: () => SlatePlugin<C>;
clone: () => SlatePlugin<C>;

extend: <EO = {}, EA = {}, ET = {}>(
extendConfig:
Expand Down
Loading

0 comments on commit 97fc0e0

Please sign in to comment.